Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
6dac40a7
Commit
6dac40a7
authored
Mar 23, 2006
by
Tom Zanussi
Committed by
Jens Axboe
Mar 23, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] relay: consolidate sendfile() and read() code
Signed-off-by:
Jens Axboe
<
axboe@suse.de
>
parent
221415d7
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
91 additions
and
84 deletions
+91
-84
kernel/relay.c
kernel/relay.c
+91
-84
No files found.
kernel/relay.c
View file @
6dac40a7
...
@@ -866,131 +866,138 @@ static size_t relay_file_read_end_pos(struct rchan_buf *buf,
...
@@ -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
* subbuf_read_actor - read up to one subbuf's worth of data
* @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.
*/
*/
static
ssize_t
relay_file_read
(
struct
file
*
filp
,
static
int
subbuf_read_actor
(
size_t
read_start
,
char
__user
*
buffer
,
struct
rchan_buf
*
buf
,
size_t
count
,
size_t
avail
,
loff_t
*
ppos
)
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
;
void
*
from
;
int
ret
=
0
;
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
;
from
=
buf
->
start
+
read_start
;
from
=
buf
->
start
+
read_start
;
ret
=
count
=
min
(
count
,
avail
)
;
ret
=
avail
;
if
(
copy_to_user
(
buffer
,
from
,
count
))
{
if
(
copy_to_user
(
desc
->
arg
.
data
,
from
,
avail
))
{
ret
=
-
EFAULT
;
desc
->
error
=
-
EFAULT
;
goto
out
;
ret
=
0
;
}
}
relay_file_read_consume
(
buf
,
read_start
,
count
)
;
desc
->
arg
.
data
+=
ret
;
*
ppos
=
relay_file_read_end_pos
(
buf
,
read_start
,
count
)
;
desc
->
written
+=
ret
;
out:
desc
->
count
-=
ret
;
mutex_unlock
(
&
inode
->
i_mutex
);
return
ret
;
return
ret
;
}
}
static
ssize_t
relay_file_sendsubbuf
(
struct
file
*
filp
,
loff_t
*
ppos
,
/**
size_t
count
,
read_actor_t
actor
,
* subbuf_send_actor - send up to one subbuf's worth of data
void
*
target
)
*/
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
long
pidx
,
poff
;
unsigned
int
subbuf_pages
;
unsigned
int
subbuf_pages
;
ssize_t
ret
=
0
;
int
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
;
subbuf_pages
=
buf
->
chan
->
alloc_size
>>
PAGE_SHIFT
;
subbuf_pages
=
buf
->
chan
->
alloc_size
>>
PAGE_SHIFT
;
pidx
=
(
read_start
/
PAGE_SIZE
)
%
subbuf_pages
;
pidx
=
(
read_start
/
PAGE_SIZE
)
%
subbuf_pages
;
poff
=
read_start
&
~
PAGE_MASK
;
poff
=
read_start
&
~
PAGE_MASK
;
while
(
count
)
{
while
(
avail
)
{
struct
page
*
p
=
buf
->
page_array
[
pidx
];
struct
page
*
p
=
buf
->
page_array
[
pidx
];
unsigned
int
len
;
unsigned
int
len
;
len
=
PAGE_SIZE
-
poff
;
len
=
PAGE_SIZE
-
poff
;
if
(
len
>
count
)
if
(
len
>
avail
)
len
=
count
;
len
=
avail
;
len
=
actor
(
&
desc
,
p
,
poff
,
len
);
len
=
actor
(
desc
,
p
,
poff
,
len
);
if
(
desc
->
error
)
if
(
desc
.
error
)
{
if
(
!
ret
)
ret
=
desc
.
error
;
break
;
break
;
}
count
-=
len
;
avail
-=
len
;
ret
+=
len
;
ret
+=
len
;
poff
=
0
;
poff
=
0
;
pidx
=
(
pidx
+
1
)
%
subbuf_pages
;
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
;
return
ret
;
}
}
static
ssize_t
relay_file_sendfile
(
struct
file
*
filp
,
loff_t
*
ppos
,
typedef
int
(
*
subbuf_actor_t
)
(
size_t
read_start
,
size_t
count
,
read_actor_t
actor
,
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
)
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
)
if
(
!
count
)
return
0
;
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
{
do
{
ret
=
relay_file_sendsubbuf
(
filp
,
ppos
,
count
,
actor
,
target
);
if
(
!
relay_file_read_avail
(
buf
,
*
ppos
))
if
(
ret
<
0
)
{
break
;
if
(
!
sent
)
sent
=
ret
;
read_start
=
relay_file_read_start_pos
(
*
ppos
,
buf
);
avail
=
relay_file_read_subbuf_avail
(
read_start
,
buf
);
if
(
!
avail
)
break
;
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
);
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
=
{
struct
file_operations
relay_file_operations
=
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment