Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
a9b1381b
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a9b1381b
编写于
12月 02, 2020
作者:
T
The8472
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix copy specialization not updating Take wrappers
上级
9b390e73
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
45 addition
and
14 deletion
+45
-14
library/std/src/sys/unix/fs.rs
library/std/src/sys/unix/fs.rs
+2
-1
library/std/src/sys/unix/kernel_copy.rs
library/std/src/sys/unix/kernel_copy.rs
+42
-12
library/std/src/sys/unix/kernel_copy/tests.rs
library/std/src/sys/unix/kernel_copy/tests.rs
+1
-1
未找到文件。
library/std/src/sys/unix/fs.rs
浏览文件 @
a9b1381b
...
...
@@ -1211,7 +1211,8 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
use
super
::
kernel_copy
::{
copy_regular_files
,
CopyResult
};
match
copy_regular_files
(
reader
.as_raw_fd
(),
writer
.as_raw_fd
(),
max_len
)
{
CopyResult
::
Ended
(
result
)
=>
result
,
CopyResult
::
Ended
(
bytes
)
=>
Ok
(
bytes
),
CopyResult
::
Error
(
e
,
_
)
=>
Err
(
e
),
CopyResult
::
Fallback
(
written
)
=>
match
io
::
copy
::
generic_copy
(
&
mut
reader
,
&
mut
writer
)
{
Ok
(
bytes
)
=>
Ok
(
bytes
+
written
),
Err
(
e
)
=>
Err
(
e
),
...
...
library/std/src/sys/unix/kernel_copy.rs
浏览文件 @
a9b1381b
...
...
@@ -167,10 +167,11 @@ fn copy(self) -> Result<u64> {
if
input_meta
.copy_file_range_candidate
()
&&
output_meta
.copy_file_range_candidate
()
{
let
result
=
copy_regular_files
(
readfd
,
writefd
,
max_write
);
result
.update_take
(
reader
);
match
result
{
CopyResult
::
Ended
(
Ok
(
bytes_copied
)
)
=>
return
Ok
(
bytes_copied
+
written
),
CopyResult
::
E
nded
(
err
)
=>
return
err
,
CopyResult
::
Ended
(
bytes_copied
)
=>
return
Ok
(
bytes_copied
+
written
),
CopyResult
::
E
rror
(
e
,
_
)
=>
return
Err
(
e
)
,
CopyResult
::
Fallback
(
bytes
)
=>
written
+=
bytes
,
}
}
...
...
@@ -182,20 +183,22 @@ fn copy(self) -> Result<u64> {
// fall back to the generic copy loop.
if
input_meta
.potential_sendfile_source
()
{
let
result
=
sendfile_splice
(
SpliceMode
::
Sendfile
,
readfd
,
writefd
,
max_write
);
result
.update_take
(
reader
);
match
result
{
CopyResult
::
Ended
(
Ok
(
bytes_copied
)
)
=>
return
Ok
(
bytes_copied
+
written
),
CopyResult
::
E
nded
(
err
)
=>
return
err
,
CopyResult
::
Ended
(
bytes_copied
)
=>
return
Ok
(
bytes_copied
+
written
),
CopyResult
::
E
rror
(
e
,
_
)
=>
return
Err
(
e
)
,
CopyResult
::
Fallback
(
bytes
)
=>
written
+=
bytes
,
}
}
if
input_meta
.maybe_fifo
()
||
output_meta
.maybe_fifo
()
{
let
result
=
sendfile_splice
(
SpliceMode
::
Splice
,
readfd
,
writefd
,
max_write
);
result
.update_take
(
reader
);
match
result
{
CopyResult
::
Ended
(
Ok
(
bytes_copied
)
)
=>
return
Ok
(
bytes_copied
+
written
),
CopyResult
::
E
nded
(
err
)
=>
return
err
,
CopyResult
::
Ended
(
bytes_copied
)
=>
return
Ok
(
bytes_copied
+
written
),
CopyResult
::
E
rror
(
e
,
_
)
=>
return
Err
(
e
)
,
CopyResult
::
Fallback
(
0
)
=>
{
/* use the fallback below */
}
CopyResult
::
Fallback
(
_
)
=>
{
unreachable!
(
"splice should not return > 0 bytes on the fallback path"
)
...
...
@@ -225,6 +228,9 @@ fn drain_to<W: Write>(&mut self, _writer: &mut W, _limit: u64) -> Result<u64> {
Ok
(
0
)
}
/// Updates `Take` wrappers to remove the number of bytes copied.
fn
taken
(
&
mut
self
,
_
bytes
:
u64
)
{}
/// The minimum of the limit of all `Take<_>` wrappers, `u64::MAX` otherwise.
/// This method does not account for data `BufReader` buffers and would underreport
/// the limit of a `Take<BufReader<Take<_>>>` type. Thus its result is only valid
...
...
@@ -251,6 +257,10 @@ fn drain_to<W: Write>(&mut self, writer: &mut W, limit: u64) -> Result<u64> {
(
**
self
)
.drain_to
(
writer
,
limit
)
}
fn
taken
(
&
mut
self
,
bytes
:
u64
)
{
(
**
self
)
.taken
(
bytes
);
}
fn
min_limit
(
&
self
)
->
u64
{
(
**
self
)
.min_limit
()
}
...
...
@@ -407,6 +417,11 @@ fn drain_to<W: Write>(&mut self, writer: &mut W, outer_limit: u64) -> Result<u64
Ok
(
bytes_drained
)
}
fn
taken
(
&
mut
self
,
bytes
:
u64
)
{
self
.set_limit
(
self
.limit
()
-
bytes
);
self
.get_mut
()
.taken
(
bytes
);
}
fn
min_limit
(
&
self
)
->
u64
{
min
(
Take
::
limit
(
self
),
self
.get_ref
()
.min_limit
())
}
...
...
@@ -432,6 +447,10 @@ fn drain_to<W: Write>(&mut self, writer: &mut W, outer_limit: u64) -> Result<u64
Ok
(
bytes
as
u64
+
inner_bytes
)
}
fn
taken
(
&
mut
self
,
bytes
:
u64
)
{
self
.get_mut
()
.taken
(
bytes
);
}
fn
min_limit
(
&
self
)
->
u64
{
self
.get_ref
()
.min_limit
()
}
...
...
@@ -457,10 +476,21 @@ fn fd_to_meta<T: AsRawFd>(fd: &T) -> FdMeta {
}
pub
(
super
)
enum
CopyResult
{
Ended
(
Result
<
u64
>
),
Ended
(
u64
),
Error
(
Error
,
u64
),
Fallback
(
u64
),
}
impl
CopyResult
{
fn
update_take
(
&
self
,
reader
:
&
mut
impl
CopyRead
)
{
match
*
self
{
CopyResult
::
Fallback
(
bytes
)
|
CopyResult
::
Ended
(
bytes
)
|
CopyResult
::
Error
(
_
,
bytes
)
=>
reader
.taken
(
bytes
),
}
}
}
/// linux-specific implementation that will attempt to use copy_file_range for copy offloading
/// as the name says, it only works on regular files
///
...
...
@@ -527,7 +557,7 @@ fn copy_file_range(
// - copying from an overlay filesystem in docker. reported to occur on fedora 32.
return
CopyResult
::
Fallback
(
0
);
}
Ok
(
0
)
=>
return
CopyResult
::
Ended
(
Ok
(
written
)
),
// reached EOF
Ok
(
0
)
=>
return
CopyResult
::
Ended
(
written
),
// reached EOF
Ok
(
ret
)
=>
written
+=
ret
as
u64
,
Err
(
err
)
=>
{
return
match
err
.raw_os_error
()
{
...
...
@@ -545,12 +575,12 @@ fn copy_file_range(
assert_eq!
(
written
,
0
);
CopyResult
::
Fallback
(
0
)
}
_
=>
CopyResult
::
E
nded
(
Err
(
err
)
),
_
=>
CopyResult
::
E
rror
(
err
,
written
),
};
}
}
}
CopyResult
::
Ended
(
Ok
(
written
)
)
CopyResult
::
Ended
(
written
)
}
#[derive(PartialEq)]
...
...
@@ -623,10 +653,10 @@ fn splice(
Some
(
os_err
)
if
mode
==
SpliceMode
::
Sendfile
&&
os_err
==
libc
::
EOVERFLOW
=>
{
CopyResult
::
Fallback
(
written
)
}
_
=>
CopyResult
::
E
nded
(
Err
(
err
)
),
_
=>
CopyResult
::
E
rror
(
err
,
written
),
};
}
}
}
CopyResult
::
Ended
(
Ok
(
written
)
)
CopyResult
::
Ended
(
written
)
}
library/std/src/sys/unix/kernel_copy/tests.rs
浏览文件 @
a9b1381b
...
...
@@ -217,7 +217,7 @@ fn bench_socket_pipe_socket_copy(b: &mut test::Bencher) {
);
match
probe
{
CopyResult
::
Ended
(
Ok
(
1
)
)
=>
{
CopyResult
::
Ended
(
1
)
=>
{
// splice works
}
_
=>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录