FAILED: patch "[PATCH] fuse: fix race between interrupt and resend" failed to apply to 7.1-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 7.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-7.1.y
git checkout FETCH_HEAD
git cherry-pick -x ed9c881f3b498383f73c42712b359419da42a7b0
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026083132-satiable-speak-130d@gregkh' --subject-prefix 'PATCH 7.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From ed9c881f3b498383f73c42712b359419da42a7b0 Mon Sep 17 00:00:00 2001
From: Miklos Szeredi <[email protected]>
Date: Thu, 9 Jul 2026 08:37:05 +0200
Subject: [PATCH] fuse: fix race between interrupt and resend
After commit f8fce75fedf7 ("fuse: clear intr_entry in fuse_resend and fuse_remove_pending_req") the WARN_ON(!list_empty(&req->intr_entry)) in fuse_request_free() still triggers due to the following race:
In request_wait_answer()
if (test_bit(FR_SENT, &req->flags)) -> returns true
In fuse_chan_resend()
clear_bit(FR_SENT, &req->flags)
In request_wait_answer()
queue_interrupt(req)
Fix by:
- move clearing FR_SENT inside fpq->lock
- move setting FR_PENDING inside fiq->lock
- recheck FR_SENT after acquiring fiq->lock in fuse_dev_queue_interrupt()
fs/fuse/dev.c +14 -13
@@ -240,7 +240,8 @@ void fuse_dev_queue_forget(struct fuse_iqueue *fiq,void fuse_dev_queue_interrupt (struct fuse_iqueue *fiq,struct fuse_req *req) {spin_lock (&fiq->lock); -if (list_empty (&req->intr_entry)) { +/* Repeat FR_SENT test after obtaining the lock to prevent race with fuse_resend() */ +if (list_empty (&req->intr_entry) &&test_bit (FR_SENT , &req->flags)) {list_add_tail (&req->intr_entry, &fiq->interrupts);/* * Pairs with smp_mb() implied by test_and_set_bit()
@@ -1760,7 +1761,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos,void fuse_chan_resend (struct fuse_chan *fch) {struct fuse_dev *fud; -struct fuse_req *req, *next; +struct fuse_req *req;struct fuse_iqueue *fiq = &fch->iq;LIST_HEAD (to_queue);unsigned int i;
@@ -1775,24 +1776,20 @@ void fuse_chan_resend(struct fuse_chan *fch)struct fuse_pqueue *fpq = &fud->pq;spin_lock (&fpq->lock); -for (i =0 ; i <FUSE_PQ_HASH_SIZE ; i++) -list_splice_tail_init (&fpq->processing[i], &to_queue); +for (i =0 ; i <FUSE_PQ_HASH_SIZE ; i++) { +struct list_head *this_queue = &fpq->processing[i]; + +list_for_each_entry (req, this_queue, list) +clear_bit (FR_SENT , &req->flags); +list_splice_tail_init (this_queue, &to_queue); + }spin_unlock (&fpq->lock); }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 ; }
@@ -1801,6 +1798,10 @@ void fuse_chan_resend(struct fuse_chan *fch)* intr_entry on fiq->interrupts after the request is re-queued. */ list_for_each_entry (req, &to_queue, list) { +set_bit (FR_PENDING , &req->flags); +/* mark the request as resend request */ + req->in.h.unique |=FUSE_UNIQUE_RESEND ; +if (test_bit (FR_INTERRUPTED , &req->flags))list_del_init (&req->intr_entry); }