Skip to content

Commit 204aa22

Browse files
author
Miklos Szeredi
committed
fuse: abort on fatal signal during sync init
When sync init is used and the server exits for some reason (error, crash) while processing FUSE_INIT, the filesystem creation will hang. The reason is that while all other threads will exit, the mounting thread (or process) will keep the device fd open, which will prevent an abort from happening. This is a regression from the async mount case, where the mount was done first, and the FUSE_INIT processing afterwards, in which case there's no such recursive syscall keeping the fd open. Fixes: dfb84c3 ("fuse: allow synchronous FUSE_INIT") Cc: stable@vger.kernel.org # v6.18 Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Reviewed-by: Bernd Schubert <bernd@bsbernd.com> Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
1 parent 5a6baf2 commit 204aa22

3 files changed

Lines changed: 9 additions & 1 deletion

File tree

fs/fuse/dev.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,11 @@ static void request_wait_answer(struct fuse_req *req)
570570
if (!err)
571571
return;
572572

573+
if (req->args->abort_on_kill) {
574+
fuse_abort_conn(fc);
575+
return;
576+
}
577+
573578
if (test_bit(FR_URING, &req->flags))
574579
removed = fuse_uring_remove_pending_req(req);
575580
else
@@ -676,7 +681,8 @@ ssize_t __fuse_simple_request(struct mnt_idmap *idmap,
676681
fuse_force_creds(req);
677682

678683
__set_bit(FR_WAITING, &req->flags);
679-
__set_bit(FR_FORCE, &req->flags);
684+
if (!args->abort_on_kill)
685+
__set_bit(FR_FORCE, &req->flags);
680686
} else {
681687
WARN_ON(args->nocreds);
682688
req = fuse_get_req(idmap, fm, false);

fs/fuse/fuse_i.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ struct fuse_args {
345345
bool is_ext:1;
346346
bool is_pinned:1;
347347
bool invalidate_vmap:1;
348+
bool abort_on_kill:1;
348349
struct fuse_in_arg in_args[4];
349350
struct fuse_arg out_args[2];
350351
void (*end)(struct fuse_mount *fm, struct fuse_args *args, int error);

fs/fuse/inode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1551,6 +1551,7 @@ int fuse_send_init(struct fuse_mount *fm)
15511551
int err;
15521552

15531553
if (fm->fc->sync_init) {
1554+
ia->args.abort_on_kill = true;
15541555
err = fuse_simple_request(fm, &ia->args);
15551556
/* Ignore size of init reply */
15561557
if (err > 0)

0 commit comments

Comments
 (0)