--- fs/fuse/dev.c | 9 ++++++++- fs/fuse/file.c | 1 + fs/fuse/fuse_i.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -397,6 +397,12 @@ static void request_wait_answer(struct f req->out.h.error = -EINTR; return; } + if (req->args->killable) { + req->out.h.error = -EINTR; + /* fuse_request_end() will drop final ref */ + spin_unlock(&fiq->lock); + return; + } spin_unlock(&fiq->lock); } @@ -494,7 +500,8 @@ ssize_t fuse_simple_request(struct fuse_ fuse_force_creds(req); __set_bit(FR_WAITING, &req->flags); - __set_bit(FR_FORCE, &req->flags); + if (!args->killable) + __set_bit(FR_FORCE, &req->flags); } else { WARN_ON(args->nocreds); req = fuse_get_req(fm, false); --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -504,6 +504,7 @@ static int fuse_flush(struct file *file, args.in_args[0].size = sizeof(inarg); args.in_args[0].value = &inarg; args.force = true; + args.killable = true; err = fuse_simple_request(fm, &args); if (err == -ENOSYS) { --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -261,6 +261,7 @@ struct fuse_args { bool page_zeroing:1; bool page_replace:1; bool may_block:1; + bool killable:1; struct fuse_in_arg in_args[3]; struct fuse_arg out_args[2]; void (*end)(struct fuse_mount *fm, struct fuse_args *args, int error);