aboutsummaryrefslogtreecommitdiffstats
path: root/fs/splice.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/splice.c')
-rw-r--r--fs/splice.c12
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
1012done: 1016done:
@@ -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}