fs/fuse/file.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
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 <liwang@kylinos.cn>
---
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
On Mon, May 11, 2026 at 3:14 AM Li Wang <liwang@kylinos.cn> wrote:
>
> 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 <liwang@kylinos.cn>
> ---
> 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);
> }
Hi Li,
I'm not sure I see how this change is needed since fuse_release_end()
does nothing with the error arg today. afaict the (void)error pattern
isn't typical in-kernel since W=3 isn't a standard build target. I
think it might be best to just keep the existing code as is to reduce
churn, and then if fuse_release_end() later in the future gets updated
to use the error arg, this would make more sense as part of that
change.
Thanks,
Joanne
> kfree(ff);
> }
> --
> 2.34.1
>
© 2016 - 2026 Red Hat, Inc.