Skip to content

Commit ebb0f38

Browse files
committed
fs/pipe: fix pipe buffer index use in FUSE
This was another case that Rasmus pointed out where the direct access to the pipe head and tail pointers broke on 32-bit configurations due to the type changes. As with the pipe FIONREAD case, fix it by using the appropriate helper functions that deal with the right pipe index sizing. Reported-by: Rasmus Villemoes <ravi@prevas.dk> Link: https://lore.kernel.org/all/878qpi5wz4.fsf@prevas.dk/ Fixes: 3d25216 ("fs/pipe: Read pipe->{head,tail} atomically outside pipe->mutex")Cc: Oleg > Cc: Mateusz Guzik <mjguzik@gmail.com> Cc: K Prateek Nayak <kprateek.nayak@amd.com> Cc: Swapnil Sapkal <swapnil.sapkal@amd.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent d810d4c commit ebb0f38

File tree

1 file changed

+6
-7
lines changed

1 file changed

+6
-7
lines changed

fs/fuse/dev.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,7 +2107,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
21072107
struct file *out, loff_t *ppos,
21082108
size_t len, unsigned int flags)
21092109
{
2110-
unsigned int head, tail, mask, count;
2110+
unsigned int head, tail, count;
21112111
unsigned nbuf;
21122112
unsigned idx;
21132113
struct pipe_buffer *bufs;
@@ -2124,8 +2124,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
21242124

21252125
head = pipe->head;
21262126
tail = pipe->tail;
2127-
mask = pipe->ring_size - 1;
2128-
count = head - tail;
2127+
count = pipe_occupancy(head, tail);
21292128

21302129
bufs = kvmalloc_array(count, sizeof(struct pipe_buffer), GFP_KERNEL);
21312130
if (!bufs) {
@@ -2135,8 +2134,8 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
21352134

21362135
nbuf = 0;
21372136
rem = 0;
2138-
for (idx = tail; idx != head && rem < len; idx++)
2139-
rem += pipe->bufs[idx & mask].len;
2137+
for (idx = tail; !pipe_empty(head, idx) && rem < len; idx++)
2138+
rem += pipe_buf(pipe, idx)->len;
21402139

21412140
ret = -EINVAL;
21422141
if (rem < len)
@@ -2147,10 +2146,10 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
21472146
struct pipe_buffer *ibuf;
21482147
struct pipe_buffer *obuf;
21492148

2150-
if (WARN_ON(nbuf >= count || tail == head))
2149+
if (WARN_ON(nbuf >= count || pipe_empty(head, tail)))
21512150
goto out_free;
21522151

2153-
ibuf = &pipe->bufs[tail & mask];
2152+
ibuf = pipe_buf(pipe, tail);
21542153
obuf = &bufs[nbuf];
21552154

21562155
if (rem >= ibuf->len) {

0 commit comments

Comments
 (0)