diff options
author | Tom Zanussi <zanussi@comcast.net> | 2008-05-09 07:28:36 -0400 |
---|---|---|
committer | Jens Axboe <jens.axboe@oracle.com> | 2008-05-28 08:49:27 -0400 |
commit | a82c53a0e3f57f02782330372b7adad67b417645 (patch) | |
tree | 3a4e65ab1a2420f8fc5d0091a6992d6f7e430ad8 /fs/splice.c | |
parent | 1ec7d99c16e69a9ed8ffeaa6c1846025b84bebad (diff) |
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, | |||
983 | 983 | ||
984 | while (len) { | 984 | while (len) { |
985 | size_t read_len; | 985 | size_t read_len; |
986 | loff_t pos = sd->pos; | 986 | loff_t pos = sd->pos, prev_pos = pos; |
987 | 987 | ||
988 | ret = do_splice_to(in, &pos, pipe, len, flags); | 988 | ret = do_splice_to(in, &pos, pipe, len, flags); |
989 | if (unlikely(ret <= 0)) | 989 | if (unlikely(ret <= 0)) |
@@ -998,15 +998,19 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, | |||
998 | * could get stuck data in the internal pipe: | 998 | * could get stuck data in the internal pipe: |
999 | */ | 999 | */ |
1000 | ret = actor(pipe, sd); | 1000 | ret = actor(pipe, sd); |
1001 | if (unlikely(ret <= 0)) | 1001 | if (unlikely(ret <= 0)) { |
1002 | sd->pos = prev_pos; | ||
1002 | goto out_release; | 1003 | goto out_release; |
1004 | } | ||
1003 | 1005 | ||
1004 | bytes += ret; | 1006 | bytes += ret; |
1005 | len -= ret; | 1007 | len -= ret; |
1006 | sd->pos = pos; | 1008 | sd->pos = pos; |
1007 | 1009 | ||
1008 | if (ret < read_len) | 1010 | if (ret < read_len) { |
1011 | sd->pos = prev_pos + ret; | ||
1009 | goto out_release; | 1012 | goto out_release; |
1013 | } | ||
1010 | } | 1014 | } |
1011 | 1015 | ||
1012 | done: | 1016 | done: |
@@ -1072,7 +1076,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, | |||
1072 | 1076 | ||
1073 | ret = splice_direct_to_actor(in, &sd, direct_splice_actor); | 1077 | ret = splice_direct_to_actor(in, &sd, direct_splice_actor); |
1074 | if (ret > 0) | 1078 | if (ret > 0) |
1075 | *ppos += ret; | 1079 | *ppos = sd.pos; |
1076 | 1080 | ||
1077 | return ret; | 1081 | return ret; |
1078 | } | 1082 | } |