Messages in this thread Patch in this message | | | From | Linus Torvalds <> | Date | Fri, 6 Dec 2019 12:28:06 -0800 | Subject | Re: [PATCH 0/2] pipe: Fixes [ver #2] |
| |
On Fri, Dec 6, 2019 at 5:56 AM David Sterba <dsterba@suse.cz> wrote: > > For reference, I've retested current master (b0d4beaa5a4b7d), that > incldes the 2 pipe fixes, the test still hangs.
I think I found it.
TOTALLY UNTESTED patch appended. It's whitespace-damaged and may be completely wrong. And might not fix it.
The first hunk is purely syntactic sugar - use the normal head/tail order. The second/third hunk is what I think fixes the problem: iter_file_splice_write() had the same buggy "let's cache head/tail/mask" pattern as pipe_write() had.
You can't cache them over a 'pipe_wait()' that drops the pipe lock, and there's one in splice_from_pipe_next().
Linus
--- snip snip --
diff --git a/fs/splice.c b/fs/splice.c index f2400ce7d528..fa1f3773c8cd 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -495,7 +495,7 @@ static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_des unsigned int mask = pipe->ring_size - 1; int ret;
- while (!pipe_empty(tail, head)) { + while (!pipe_empty(head, tail)) { struct pipe_buffer *buf = &pipe->bufs[tail & mask];
sd->len = buf->len; @@ -711,9 +711,7 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, splice_from_pipe_begin(&sd); while (sd.total_len) { struct iov_iter from; - unsigned int head = pipe->head; - unsigned int tail = pipe->tail; - unsigned int mask = pipe->ring_size - 1; + unsigned int head, tail, mask; size_t left; int n;
@@ -732,6 +730,10 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, } }
+ head = pipe->head; + tail = pipe->tail; + mask = pipe->ring_size - 1; + /* build the vector */ left = sd.total_len; for (n = 0; !pipe_empty(head, tail) && left && n < nbufs; tail++, n++) {
| |