Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
6dac40a7
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
6dac40a7
编写于
3月 23, 2006
作者:
T
Tom Zanussi
提交者:
Jens Axboe
3月 23, 2006
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[PATCH] relay: consolidate sendfile() and read() code
Signed-off-by:
N
Jens Axboe
<
axboe@suse.de
>
上级
221415d7
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
91 addition
and
84 deletion
+91
-84
kernel/relay.c
kernel/relay.c
+91
-84
未找到文件。
kernel/relay.c
浏览文件 @
6dac40a7
...
...
@@ -866,131 +866,138 @@ static size_t relay_file_read_end_pos(struct rchan_buf *buf,
}
/**
* relay_file_read - read file op for relay files
* @filp: the file
* @buffer: the userspace buffer
* @count: number of bytes to read
* @ppos: position to read from
*
* Reads count bytes or the number of bytes available in the
* current sub-buffer being read, whichever is smaller.
* subbuf_read_actor - read up to one subbuf's worth of data
*/
static
ssize_t
relay_file_read
(
struct
file
*
filp
,
char
__user
*
buffer
,
size_t
count
,
loff_t
*
ppos
)
static
int
subbuf_read_actor
(
size_t
read_start
,
struct
rchan_buf
*
buf
,
size_t
avail
,
read_descriptor_t
*
desc
,
read_actor_t
actor
)
{
struct
rchan_buf
*
buf
=
filp
->
private_data
;
struct
inode
*
inode
=
filp
->
f_dentry
->
d_inode
;
size_t
read_start
,
avail
;
ssize_t
ret
=
0
;
void
*
from
;
mutex_lock
(
&
inode
->
i_mutex
);
if
(
!
relay_file_read_avail
(
buf
,
*
ppos
))
goto
out
;
read_start
=
relay_file_read_start_pos
(
*
ppos
,
buf
);
avail
=
relay_file_read_subbuf_avail
(
read_start
,
buf
);
if
(
!
avail
)
goto
out
;
int
ret
=
0
;
from
=
buf
->
start
+
read_start
;
ret
=
count
=
min
(
count
,
avail
)
;
if
(
copy_to_user
(
buffer
,
from
,
count
))
{
ret
=
-
EFAULT
;
goto
out
;
ret
=
avail
;
if
(
copy_to_user
(
desc
->
arg
.
data
,
from
,
avail
))
{
desc
->
error
=
-
EFAULT
;
ret
=
0
;
}
relay_file_read_consume
(
buf
,
read_start
,
count
)
;
*
ppos
=
relay_file_read_end_pos
(
buf
,
read_start
,
count
)
;
out:
mutex_unlock
(
&
inode
->
i_mutex
);
desc
->
arg
.
data
+=
ret
;
desc
->
written
+=
ret
;
desc
->
count
-=
ret
;
return
ret
;
}
static
ssize_t
relay_file_sendsubbuf
(
struct
file
*
filp
,
loff_t
*
ppos
,
size_t
count
,
read_actor_t
actor
,
void
*
target
)
/**
* subbuf_send_actor - send up to one subbuf's worth of data
*/
static
int
subbuf_send_actor
(
size_t
read_start
,
struct
rchan_buf
*
buf
,
size_t
avail
,
read_descriptor_t
*
desc
,
read_actor_t
actor
)
{
struct
rchan_buf
*
buf
=
filp
->
private_data
;
read_descriptor_t
desc
;
size_t
read_start
,
avail
;
unsigned
long
pidx
,
poff
;
unsigned
int
subbuf_pages
;
ssize_t
ret
=
0
;
if
(
!
relay_file_read_avail
(
buf
,
*
ppos
))
return
0
;
read_start
=
relay_file_read_start_pos
(
*
ppos
,
buf
);
avail
=
relay_file_read_subbuf_avail
(
read_start
,
buf
);
if
(
!
avail
)
return
0
;
count
=
min
(
count
,
avail
);
desc
.
written
=
0
;
desc
.
count
=
count
;
desc
.
arg
.
data
=
target
;
desc
.
error
=
0
;
int
ret
=
0
;
subbuf_pages
=
buf
->
chan
->
alloc_size
>>
PAGE_SHIFT
;
pidx
=
(
read_start
/
PAGE_SIZE
)
%
subbuf_pages
;
poff
=
read_start
&
~
PAGE_MASK
;
while
(
count
)
{
while
(
avail
)
{
struct
page
*
p
=
buf
->
page_array
[
pidx
];
unsigned
int
len
;
len
=
PAGE_SIZE
-
poff
;
if
(
len
>
count
)
len
=
count
;
if
(
len
>
avail
)
len
=
avail
;
len
=
actor
(
&
desc
,
p
,
poff
,
len
);
if
(
desc
.
error
)
{
if
(
!
ret
)
ret
=
desc
.
error
;
len
=
actor
(
desc
,
p
,
poff
,
len
);
if
(
desc
->
error
)
break
;
}
count
-=
len
;
avail
-=
len
;
ret
+=
len
;
poff
=
0
;
pidx
=
(
pidx
+
1
)
%
subbuf_pages
;
}
if
(
ret
>
0
)
{
relay_file_read_consume
(
buf
,
read_start
,
ret
);
*
ppos
=
relay_file_read_end_pos
(
buf
,
read_start
,
ret
);
}
return
ret
;
}
static
ssize_t
relay_file_sendfile
(
struct
file
*
filp
,
loff_t
*
ppos
,
size_t
count
,
read_actor_t
actor
,
typedef
int
(
*
subbuf_actor_t
)
(
size_t
read_start
,
struct
rchan_buf
*
buf
,
size_t
avail
,
read_descriptor_t
*
desc
,
read_actor_t
actor
);
/**
* relay_file_read_subbufs - read count bytes, bridging subbuf boundaries
*/
static
inline
ssize_t
relay_file_read_subbufs
(
struct
file
*
filp
,
loff_t
*
ppos
,
size_t
count
,
subbuf_actor_t
subbuf_actor
,
read_actor_t
actor
,
void
*
target
)
{
ssize_t
sent
=
0
,
ret
=
0
;
struct
rchan_buf
*
buf
=
filp
->
private_data
;
size_t
read_start
,
avail
;
read_descriptor_t
desc
;
int
ret
;
if
(
!
count
)
return
0
;
mutex_lock
(
&
filp
->
f_dentry
->
d_inode
->
i_mutex
);
desc
.
written
=
0
;
desc
.
count
=
count
;
desc
.
arg
.
data
=
target
;
desc
.
error
=
0
;
mutex_lock
(
&
filp
->
f_dentry
->
d_inode
->
i_mutex
);
do
{
ret
=
relay_file_sendsubbuf
(
filp
,
ppos
,
count
,
actor
,
target
);
if
(
ret
<
0
)
{
if
(
!
sent
)
sent
=
ret
;
if
(
!
relay_file_read_avail
(
buf
,
*
ppos
))
break
;
read_start
=
relay_file_read_start_pos
(
*
ppos
,
buf
);
avail
=
relay_file_read_subbuf_avail
(
read_start
,
buf
);
if
(
!
avail
)
break
;
}
count
-=
ret
;
sent
+=
ret
;
}
while
(
count
&&
ret
);
avail
=
min
(
desc
.
count
,
avail
);
ret
=
subbuf_actor
(
read_start
,
buf
,
avail
,
&
desc
,
actor
);
if
(
desc
.
error
<
0
)
break
;
if
(
ret
)
{
relay_file_read_consume
(
buf
,
read_start
,
ret
);
*
ppos
=
relay_file_read_end_pos
(
buf
,
read_start
,
ret
);
}
}
while
(
desc
.
count
&&
ret
);
mutex_unlock
(
&
filp
->
f_dentry
->
d_inode
->
i_mutex
);
return
sent
;
return
desc
.
written
;
}
static
ssize_t
relay_file_read
(
struct
file
*
filp
,
char
__user
*
buffer
,
size_t
count
,
loff_t
*
ppos
)
{
return
relay_file_read_subbufs
(
filp
,
ppos
,
count
,
subbuf_read_actor
,
NULL
,
buffer
);
}
static
ssize_t
relay_file_sendfile
(
struct
file
*
filp
,
loff_t
*
ppos
,
size_t
count
,
read_actor_t
actor
,
void
*
target
)
{
return
relay_file_read_subbufs
(
filp
,
ppos
,
count
,
subbuf_send_actor
,
actor
,
target
);
}
struct
file_operations
relay_file_operations
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录