Re: [PATCH] fuse: serialize resend state transitions with fiq->lock

Mingyu He <[email protected]>
Newsgroups dev.linux.lists.fuse-devel
Message-ID <CAAoBcuSRsSnPo3jK11N0dxq6zXZtivfXeE-4SPL7NUKhmQsc=w@mail.gmail.com>
oops,  I found that Jun Yang <[email protected]> also sent an email
that have fixed same problem.  Recently I am working for fuse recovery
mechanism for my company, and found that problem. I was working for
this problem on 4th Aug and sent this email the next day, so I didn't
noticed that someone else had already sent an email before me.

As Jun Yang has resolved this issue more completely and sent email
before mine, I suppose to ignore my email and consider his solution.

Thanks!

Link: https://lore.kernel.org/all/[email protected]/
https://lore.kernel.org/all/[email protected]/

On Wed, Aug 5, 2026 at 3:10 PM Runli <[email protected]> wrote:
>
> fuse_chan_resend() moves processing requests to a private to_queue, then
> sets FR_PENDING before taking fiq->lock. A fatal signal can consequently
> remove and free a request while it is still being prepared for resend:
>
>   CPU 0 (request holder)          CPU 1 (resend)
>   ----------------------          ----------------
>   request_wait_answer()
>                                   req moved to private to_queue
>                                   set_bit(FR_PENDING)
>   fatal signal
>   fuse_remove_pending_req()
>     list_del(&req->list)
>     __fuse_put_request(req)
>   fuse_put_request(req)
>     free req
>                                   clear_bit(FR_SENT)
>                                   update req->in.h.unique
>
> Hold fiq->lock while updating the requests and moving them to
> fiq->pending, serializing the transition with fuse_remove_pending_req().
>
> Connected requests retain the same flags, unique IDs, and queue order. On
> disconnection, fuse_dev_end_requests() still ends every request, while
> requests that were never requeued are no longer marked pending or resent.
>
> This also combines the two linear list walks into one, reducing the total
> iteration count from 2n to n. The fiq->lock critical section remains O(n).
>
> Fixes: 760eac73f9f6 ("fuse: Introduce a new notification type for resend pending requests")
> Signed-off-by: Runli <[email protected]>
> ---
>  fs/fuse/dev.c | 24 ++++++++++--------------
>  1 file changed, 10 insertions(+), 14 deletions(-)
>
> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
> index 5763a7cd3b37..fc1f5b9f100c 100644
> --- a/fs/fuse/dev.c
> +++ b/fs/fuse/dev.c
> @@ -1781,26 +1781,22 @@ void fuse_chan_resend(struct fuse_chan *fch)
>         }
>         spin_unlock(&fch->lock);
>
> -       list_for_each_entry_safe(req, next, &to_queue, list) {
> -               set_bit(FR_PENDING, &req->flags);
> -               clear_bit(FR_SENT, &req->flags);
> -               /* mark the request as resend request */
> -               req->in.h.unique |= FUSE_UNIQUE_RESEND;
> -       }
> -
>         spin_lock(&fiq->lock);
>         if (!fiq->connected) {
>                 spin_unlock(&fiq->lock);
> -               list_for_each_entry(req, &to_queue, list)
> -                       clear_bit(FR_PENDING, &req->flags);
>                 fuse_dev_end_requests(&to_queue);
>                 return;
>         }
> -       /*
> -        * Remove interrupt entries for resent requests to prevent stale
> -        * intr_entry on fiq->interrupts after the request is re-queued.
> -        */
> -       list_for_each_entry(req, &to_queue, list) {
> +
> +       list_for_each_entry_safe(req, next, &to_queue, list) {
> +               set_bit(FR_PENDING, &req->flags);
> +               clear_bit(FR_SENT, &req->flags);
> +               /* mark the request as resend request */
> +               req->in.h.unique |= FUSE_UNIQUE_RESEND;
> +               /*
> +                * Remove interrupt entries for resent requests to prevent stale
> +                * intr_entry on fiq->interrupts after the request is re-queued.
> +                */
>                 if (test_bit(FR_INTERRUPTED, &req->flags))
>                         list_del_init(&req->intr_entry);
>         }
> --
> 2.47.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.