|
@@ -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;
|
|
|
}
|