diff options
author | Tom Zanussi <zanussi@comcast.net> | 2008-05-09 13:28:36 +0200 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-05-28 14:49:27 +0200 |
commit | a82c53a0e3f57f02782330372b7adad67b417645 (patch) | |
tree | 3a4e65ab1a2420f8fc5d0091a6992d6f7e430ad8 /fs/splice.c | |
parent | 1ec7d99c16e69a9ed8ffeaa6c1846025b84bebad (diff) | |
download | lwn-a82c53a0e3f57f02782330372b7adad67b417645.tar.gz lwn-a82c53a0e3f57f02782330372b7adad67b417645.zip |
splice: fix sendfile() issue with relay
Splice isn't always incrementing the ppos correctly, which broke
relay splice.
Signed-off-by: Tom Zanussi <zanussi@comcast.net>
Tested-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'fs/splice.c')
-rw-r--r-- | fs/splice.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/splice.c b/fs/splice.c index 78150038b584..a048ad2130c3 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -983,7 +983,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, while (len) { size_t read_len; - loff_t pos = sd->pos; + loff_t pos = sd->pos, prev_pos = pos; ret = do_splice_to(in, &pos, pipe, len, flags); if (unlikely(ret <= 0)) @@ -998,15 +998,19 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, * could get stuck data in the internal pipe: */ ret = actor(pipe, sd); - if (unlikely(ret <= 0)) + if (unlikely(ret <= 0)) { + sd->pos = prev_pos; goto out_release; + } bytes += ret; len -= ret; sd->pos = pos; - if (ret < read_len) + if (ret < read_len) { + sd->pos = prev_pos + ret; goto out_release; + } } done: @@ -1072,7 +1076,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, ret = splice_direct_to_actor(in, &sd, direct_splice_actor); if (ret > 0) - *ppos += ret; + *ppos = sd.pos; return ret; } |