fuse_file_put() queues asynchronous FUSE_RELEASE via fuse_simple_background(). When queueing fails, the failure branch always passed -ENOTCONN into fuse_release_end(). fuse_simple_background() can however fail for multiple reasons with different return values, such as -ENOMEM or -EINTR. Pass the actual negative errno into fuse_release_end(). A similar pattern occurs when fuse_send_readpages() calls fuse_readpages_end(). In that case, if sending the request fails, fuse_readpages_end() is invoked directly using the error value returned by the sending function as an argument. Furthermore, the same applies to fuse_async_req_send() calling fuse_aio_complete_req(). This patch aligns with those cases. The parameter "error" is currently unused in fuse_release_end(). While removing it seems like the better choice, however, while fuse_file_put() calls fuse_release_end() directly if sending the async request fails, it also registers fuse_release_end() as the success callback. Consequently, fuse_release_end() must strictly adhere to the callback signature; removing any parameter would trigger a compilation error. Add an explicit (void)error in fuse_release_end() so builds that enable -Wunused-parameter (for example make W=3) stay clean. Signed-off-by: Li Wang --- Changes since v1: - Amend commit message to clarify the reasoning behind the code changes. fs/fuse/file.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 3bdab8d03373..8b7badb7721a 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -96,6 +96,8 @@ static void fuse_release_end(struct fuse_args *args, int error) { struct fuse_release_args *ra = container_of(args, typeof(*ra), args); + (void)error; + iput(ra->inode); kfree(ra); } @@ -117,6 +119,8 @@ static void fuse_file_put(struct fuse_file *ff, bool sync) fuse_simple_request(ff->fm, args); fuse_release_end(args, 0); } else { + int err; + /* * DAX inodes may need to issue a number of synchronous * request for clearing the mappings. @@ -124,9 +128,10 @@ static void fuse_file_put(struct fuse_file *ff, bool sync) if (ra && ra->inode && FUSE_IS_DAX(ra->inode)) args->may_block = true; args->end = fuse_release_end; - if (fuse_simple_background(ff->fm, args, - GFP_KERNEL | __GFP_NOFAIL)) - fuse_release_end(args, -ENOTCONN); + err = fuse_simple_background(ff->fm, args, + GFP_KERNEL | __GFP_NOFAIL); + if (err) + fuse_release_end(args, err); } kfree(ff); } -- 2.34.1