[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <b6ae6cc54272011a24130723f3344616602ebb55.1703126594.git.nabijaczleweli@nabijaczleweli.xyz>
Date: Thu, 21 Dec 2023 04:08:56 +0100
From:
Ahelenia Ziemiańska <nabijaczleweli@...ijaczleweli.xyz>
Cc: Jens Axboe <axboe@...nel.dk>, Christian Brauner <brauner@...nel.org>,
Alexander Viro <viro@...iv.linux.org.uk>, linux-fsdevel@...r.kernel.org,
Miklos Szeredi <miklos@...redi.hu>, linux-kernel@...r.kernel.org
Subject: [PATCH v2 03/11] fuse: fuse_dev_splice_read: use nonblocking I/O
Otherwise we risk sleeping with the pipe locked for indeterminate
lengths of time ‒ since FUSE is usually installed with the fusermount
helper suid, given
cat > fusedev.c <<^D
#define _GNU_SOURCE
#include <fcntl.h>
#define FUSE_USE_VERSION 30
#include <fuse.h>
static void *fop_init(struct fuse_conn_info *conn, struct fuse_config *cfg)
{
for (;;)
splice(3, 0, 4, 0, 128 * 1024 * 1024, 0);
}
static const struct fuse_operations fops = { .init = fop_init };
int main(int argc, char **argv)
{
return fuse_main(argc, argv, &fops, NULL);
}
^D
cc nullsleep.c $(pkg-config fuse3 --cflags --libs) -o nullsleep
mkfifo fifo
mkdir dir
./nullsleep dir 4>fifo &
read -r _ < fifo &
sleep 0.1
echo zupa > fifo
nullsleep used to sleep in splice and the shell used to enter an
uninterruptible sleep in open("fifo");
now the splice returns -EAGAIN and the whole program completes.
Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli@...ijaczleweli.xyz>
---
fs/fuse/dev.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 1a8f82f478cb..4e8caf66c01e 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -1202,7 +1202,8 @@ __releases(fiq->lock)
* the 'sent' flag.
*/
static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
- struct fuse_copy_state *cs, size_t nbytes)
+ struct fuse_copy_state *cs, size_t nbytes,
+ bool nonblock)
{
ssize_t err;
struct fuse_conn *fc = fud->fc;
@@ -1238,7 +1239,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file,
break;
spin_unlock(&fiq->lock);
- if (file->f_flags & O_NONBLOCK)
+ if (nonblock)
return -EAGAIN;
err = wait_event_interruptible_exclusive(fiq->waitq,
!fiq->connected || request_pending(fiq));
@@ -1364,7 +1365,8 @@ static ssize_t fuse_dev_read(struct kiocb *iocb, struct iov_iter *to)
fuse_copy_init(&cs, 1, to);
- return fuse_dev_do_read(fud, file, &cs, iov_iter_count(to));
+ return fuse_dev_do_read(fud, file, &cs, iov_iter_count(to),
+ file->f_flags & O_NONBLOCK);
}
static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
@@ -1388,7 +1390,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,
fuse_copy_init(&cs, 1, NULL);
cs.pipebufs = bufs;
cs.pipe = pipe;
- ret = fuse_dev_do_read(fud, in, &cs, len);
+ ret = fuse_dev_do_read(fud, in, &cs, len, true);
if (ret < 0)
goto out;
--
2.39.2
Download attachment "signature.asc" of type "application/pgp-signature" (834 bytes)
Powered by blists - more mailing lists