aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/splice.c12
-rw-r--r--kernel/relay.c2
2 files changed, 9 insertions, 5 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}
diff --git a/kernel/relay.c b/kernel/relay.c
index bc24dcdc570f..7de644cdec43 100644
--- a/kernel/relay.c
+++ b/kernel/relay.c
@@ -1191,7 +1191,7 @@ static ssize_t relay_file_splice_read(struct file *in,
1191 ret = 0; 1191 ret = 0;
1192 spliced = 0; 1192 spliced = 0;
1193 1193
1194 while (len) { 1194 while (len && !spliced) {
1195 ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret); 1195 ret = subbuf_splice_actor(in, ppos, pipe, len, flags, &nonpad_ret);
1196 if (ret < 0) 1196 if (ret < 0)
1197 break; 1197 break;