summaryrefslogtreecommitdiff
path: root/include/linux/node.h
diff options
context:
space:
mode:
authorChris Mason <clm@meta.com>2026-06-09 03:28:55 +0300
committerMiklos Szeredi <mszeredi@redhat.com>2026-06-15 15:06:14 +0300
commitbea4fe98204b6ce7eb8e29f7bf867dd7619b3ddd (patch)
tree32136080b05e6eeafcbc17985dc417be1d7ef8e7 /include/linux/node.h
parent198f45eeb9f78b2a2d6d8be95e4e43468eb2c6bc (diff)
downloadlinux-bea4fe98204b6ce7eb8e29f7bf867dd7619b3ddd.tar.xz
fuse-uring: end fuse_req on io-uring cancel task work
When io_uring delivers task work with tw.cancel set (PF_EXITING, PF_KTHREAD fallback, or percpu_ref_is_dying on the ring context), fuse_uring_send_in_task() takes the cancel branch, assigns -ECANCELED, and falls through to fuse_uring_send(). That path only flips the entry to FRRS_USERSPACE and completes the io_uring cmd; it never discharges the ring entry's owning reference to the fuse_req that fuse_uring_add_req_to_ring_ent() handed it at dispatch time. fuse_uring_send_in_task() tw.cancel == true err = -ECANCELED fuse_uring_send(ent, cmd, err, issue_flags) ent->state = FRRS_USERSPACE list_move(&ent->list, &queue->ent_in_userspace) ent->cmd = NULL io_uring_cmd_done(-ECANCELED) /* ent->fuse_req still set, req still hashed */ The fuse_req stays linked on fpq->processing[hash] and fuse_request_end() is never invoked. The originating syscall thread blocks in D-state in request_wait_answer() until fuse_abort_conn() runs, which can be the entire connection lifetime. For FR_BACKGROUND requests fc->num_background is never decremented either, so repeated cancels inflate the counter until max_background is hit and all later background ops stall. tw.cancel does not imply a connection abort (e.g. a single io_uring worker thread exits while the fuse connection stays up), so this cannot be left for fuse_abort_conn() to clean up. Ending the req but still routing the entry through fuse_uring_send() is not enough: that leaves a req-less entry on ent_in_userspace, and ent_list_request_expired() dereferences ent->fuse_req unconditionally on the head of that list, which would then NULL-deref. Fix the cancel branch to release the entry directly. Remove it from the queue, complete the io_uring cmd, end the fuse_req, free the entry, and drop its queue_refs (waking the teardown waiter if it was the last). Fixes: c2c9af9a0b13 ("fuse: Allow to queue fg requests through io-uring") Cc: stable@vger.kernel.org Reviewed-by: Joanne Koong <joannelkoong@gmail.com> Assisted-by: kres (claude-opus-4-7) Signed-off-by: Chris Mason <clm@meta.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Diffstat (limited to 'include/linux/node.h')
0 files changed, 0 insertions, 0 deletions