Skip to content

Commit

Permalink
splice: direct splicing updates ppos twice
Browse files Browse the repository at this point in the history
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> reported that he's noticed
nfsd read corruption in recent kernels, and did the hard work of
discovering that it's due to splice updating the file position twice.
This means that the next operation would start further ahead than it
should.

nfsd_vfs_read()
    splice_direct_to_actor()
        while(len) {
            do_splice_to()                     [update sd->pos]
                -> generic_file_splice_read()  [read from sd->pos]
            nfsd_direct_splice_actor()
                -> __splice_from_pipe()        [update sd->pos]

There's nothing wrong with the core splice code, but the direct
splicing is an addon that calls both input and output paths.
So it has to take care in locally caching offset so it remains correct.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
  • Loading branch information
Jens Axboe committed Jul 16, 2007
1 parent 56a68a5 commit bcd4f3a
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion fs/splice.c
Original file line number Diff line number Diff line change
Expand Up @@ -1061,8 +1061,9 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,

while (len) {
size_t read_len;
loff_t pos = sd->pos;

ret = do_splice_to(in, &sd->pos, pipe, len, flags);
ret = do_splice_to(in, &pos, pipe, len, flags);
if (unlikely(ret <= 0))
goto out_release;

Expand All @@ -1080,6 +1081,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,

bytes += ret;
len -= ret;
sd->pos = pos;

if (ret < read_len)
goto out_release;
Expand Down

0 comments on commit bcd4f3a

Please sign in to comment.