Skip to content

[rlc-10/6.12.0-211.43.1.el10_2] Multiple patches tested (41 commits) - #1539

Open
ciq-kernel-automation[bot] wants to merge 41 commits into
rlc-10/6.12.0-211.43.1.el10_2from
{bmastbergen_fuse_iouring}_rlc-10/6.12.0-211.43.1.el10_2
Open

[rlc-10/6.12.0-211.43.1.el10_2] Multiple patches tested (41 commits)#1539
ciq-kernel-automation[bot] wants to merge 41 commits into
rlc-10/6.12.0-211.43.1.el10_2from
{bmastbergen_fuse_iouring}_rlc-10/6.12.0-211.43.1.el10_2

Conversation

@ciq-kernel-automation

Copy link
Copy Markdown

Summary

This PR has been automatically created after successful completion of all CI stages.

Commit Message(s)

fuse: rename to fuse_dev_end_requests and make non-static

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 92270d076115ae81b83f0605703602d2d5a866e2
fuse: Move fuse_get_dev to header file

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 867d93dcdede5ea453543085d1ed0bf43cde60de
fuse: Move request bits

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 88be7aa98d91f5761f8764273ebd961915e4632d
fuse: make args->in_args[0] to be always the header

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 7ccd86ba3a485a8bc33478776eb7053d9adb7816
upstream-diff | Context conflict on missing fs/fuse/fuse_i.h commit
	41748675c0bf -virtiofs: use pages instead of pointer for kernel direct IO
fuse: {io-uring} Handle SQEs - register commands

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 24fe962c86f55347385933a1b06ca71b60854690
upstream-diff | Context diff due to missing commit on fs/fuse/Makefile
	2b3933b1e0a0 - fuse: enable dynamic configuration of fuse max pages
			limit (FUSE_MAX_MAX_PAGES)
	Context difference due to future feature enabled earlier in git
	log order as well.
fuse: Make fuse_copy non static

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit d0f9c62aaf7a98412b46a91fe7daad76b316b3b7
fuse: Add fuse-io-uring handling into fuse_copy

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit f773a7c2c3d934d00542c6471170066d150d152f
fuse: {io-uring} Make hash-list req unique finding functions non-static

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 3821336530616776414aa7a879640052b89def28
fuse: Add io-uring sqe commit and fetch support

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit c090c8abae4b6b77a1bee116aa6c385456ebef96
fuse: {io-uring} Handle teardown of ring entries

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 4a9bfb9b6850fec0685447aed280533cf980de70
fuse: {io-uring} Make fuse_dev_queue_{interrupt,forget} non-static

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit ba74ba571189668697a8d8da906ad6d44762ebc6
fuse: Allow to queue fg requests through io-uring

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit c2c9af9a0b13261c36909036057a116f2edb5e1a
fuse: Allow to queue bg requests through io-uring

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 857b0263f30eebe13ab4b6a65156a0d6c8fc2210
fuse: {io-uring} Prevent mount point hang on fuse-server termination

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit b6236c8407cba5d7a108facb1bcfab24994d3814
fuse: block request allocation until io-uring init is complete

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bernd@bsbernd.com>
commit 3393ff964e0fa5def66570c54a4612bf9df06b76
upstream-diff | Context conflict on missing fs/fuse/fuse_i.h commit
            41748675c0bf -virtiofs: use pages instead of pointer for kernel direct IO
fuse: enable fuse-over-io-uring

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 786412a73e7ee5b00ef3437bbf2f3a250759b2ae
fuse: prevent disabling io-uring on active connections

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 2d4fde59fd502a65c1698b61ad4d0f10a9ab665a
fuse: fix uring race condition for null dereference of fc

jira SECO-478
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit d9ecc77193cad25402ff5517fb26fb22b4db0e10
fuse: fix possible deadlock if rings are never initialized

jira SECO-478
RFE: FUSE_IO_URING
commit-author Luis Henriques <luis@igalia.com>
commit d55011469b41d9da6c06cb1c4a4da7a87fe155bc
fuse: removed unused function fuse_uring_create() from header

jira SECO-478
RFE: FUSE_IO_URING
commit-author Luis Henriques <luis@igalia.com>
commit 841c7b812c038661e4f659d1b9c9a366c6d24b71
fuse: {io-uring} Fix a possible req cancellation race

jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 09098e62e4be8f0755e58d6078aaf27cbd9a3a8d
fuse: remove unneeded atomic set in uring creation

jira SECO-478
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 2d066800a4276340a97acc75c148892eb6f8781a
fuse: missing copy_finish in fuse-over-io-uring argument copies

jira SECO-478
cve CVE-2025-68791
RFE: FUSE_IO_URING
commit-author Cheng Ding <cding@ddn.com>
commit 6e0d7f7f4a43ac8868e98c87ecf48805aa8c24dd
upstream-diff |
            Context diffs from missing upstream type changes
            (bool write, is_uring = true) and surrounding declarations
fuse: fix io-uring list corruption for terminated non-committed requests

jira SECO-478
cve CVE-2025-68805
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 95c39eef7c2b666026c69ab5b30471da94ea2874
fuse-uring: fix EFAULT clobber in fuse_uring_commit

jira SECO-478
cve CVE-2026-64264
RFE: FUSE_IO_URING
commit-author Chris Mason <clm@meta.com>
commit 3a0a8bc51a13951c5141262bf770eeea3e0b6228
fuse-uring: fix data races on ring->ready

jira SECO-478
cve CVE-2026-64588
RFE: FUSE_IO_URING
commit-author Chris Mason <clm@meta.com>
commit 46725a0056c884cf58a6897f222892807327d82d
fuse-uring: fix race between registration and connection abortion

jira SECO-478
cve CVE-2026-68095
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 952b5d36f6a298f57c52a59e72076c69386a8aaf
upstream-diff |
            fch->lock/fch->connected changed to fc->lock/fc->connected
            (fuse_chan struct not present in this kernel)
fuse-uring: check connection abort during ring creation

jira SECO-478
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit c146284c4355e96550e50e8f6e694223d107b621
upstream-diff |
            fch->lock/fch->connected changed to fc->lock/fc->connected
            in fuse_uring_do_register() already applied in 703224b.
            Only the fuse_uring_create() hunk is new.
fuse-uring: fix moving cancelled entry to ent_in_userspace list

jira SECO-478
cve CVE-2026-64263
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 198f45eeb9f78b2a2d6d8be95e4e43468eb2c6bc
upstream-diff |
            io_uring_cmd_done() uses 4 args (res2=0) vs upstream 3 args.
            list_move used instead of list_move_tail.
fuse-uring: end fuse_req on io-uring cancel task work

jira SECO-478
cve CVE-2026-64262
RFE: FUSE_IO_URING
commit-author Chris Mason <clm@meta.com>
commit bea4fe98204b6ce7eb8e29f7bf867dd7619b3ddd
upstream-diff |
            fuse_uring_send_in_task has different signature
            (missing io_tw_req/io_tw_token_t API in this kernel)
            io_uring_cmd_done() call corrected to pass 4 args
            (res2=0 was missing in upstream adaptation)
fuse-uring: Avoid use-after-free in fuse_uring_async_stop_queues

jira SECO-478
cve CVE-2026-64261
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bernd@bsbernd.com>
commit d351da75066955144515cb2f9aa959f24a04287a
upstream-diff |
            ring->fc used instead of ring->chan->conn
fuse-uring: Avoid queue->stopped races and set/read that value under lock

jira SECO-478
cve CVE-2026-64260
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bernd@bsbernd.com>
commit b70a3aca16934c196f92abb17b01c1647b9bb63c
upstream-diff |
            ring->fc used instead of ring->chan->conn
fuse-uring: make a fuse_req on SQE commit only findable after memcpy

jira SECO-478
cve CVE-2026-64259
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bernd@bsbernd.com>
commit 1efd3d474fc0ba74dfd984249bca78807d739812
upstream-diff |
            list_move used instead of list_move_tail and
            io_uring_cmd_done has extra arg (older API in this kernel)
fuse-uring: remove request-less entries from ent_w_req_queue to fix NULL deref

jira SECO-478
cve CVE-2026-64258
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 1c57a69be962d459c5e705f5cb4355b841b3461c
fuse: fix io-uring background queue dispatch on request completion

jira SECO-478
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 31da059891bd3be9c6e59280b8e1777ead90db34
upstream-diff |
            fuse_copy_init uses int write vs bool write in this kernel
fuse-uring: clear ent->fuse_req in commit_fetch error path

jira SECO-478
RFE: FUSE_IO_URING
commit-author Zhenghang Xiao <kipreyyy@gmail.com>
commit 7d87a5a284bb34edb3f4e7e312ef403b3385a7b7
configs: enable CONFIG_FUSE_IO_URING=y on all supported architectures

jira SECO-478
RFE: FUSE_IO_URING
selftests: filesystems: Add functional test for the abort file in fusectl

jira SECO-478
RFE: FUSE_IO_URING
commit-author Chen Linxuan <chenlinxuan@uniontech.com>
commit 1a7b13781b0d48312e0ead2585776b0afd1343cd
selftests/fuse: adapt fuse_mnt to libfuse3 API

On systems with only libfuse3-devel installed (no libfuse2-devel),
fuse_mnt.c fails to compile because fuse3 requires API version 30+.
selftests/fuse: add ACL_DONT_CACHE regression test

jira SECO-478
RFE: FUSE_IO_URING
commit-author Amir Goldstein <amir73il@gmail.com>
commit 9acb102522b92f24fba6b238b3668a4d9dfcb592
upstream-diff |
            kselftest_harness.h include uses relative path
            (../../kselftest_harness.h) because commit e6fbd1759c9e
            ("selftests: complete kselftest include centralization")
            is not present in this tree.
selftests/fuse: add FUSE io-uring integration test

Add a kselftest for the FUSE io-uring request dispatch path.  A
minimal in-memory FUSE daemon runs in a thread, negotiates
FUSE_OVER_IO_URING during FUSE_INIT, and handles requests through
FUSE_IO_URING_CMD_REGISTER / FUSE_IO_URING_CMD_COMMIT_AND_FETCH.
An atomic counter verifies requests are served through io_uring.

Test Results

✅ Build Stage

Architecture Build Time Total Time
x86_64 39m 2s 39m 52s
aarch64 25m 23s 26m 5s

✅ Boot Verification

✅ Kernel Selftests

Architecture Passed Failed Compared Against Status
x86_64 429 63 rlc-10/6.12.0-211.43.1.el10_2 ✅ No regressions
aarch64 375 60 rlc-10/6.12.0-211.43.1.el10_2 ✅ No regressions

✅ LTP Results

Architecture Passed Failed Compared Against Status
x86_64 1478 80 rlc-10/6.12.0-211.43.1.el10_2 ✅ No regressions
aarch64 1451 81 rlc-10/6.12.0-211.43.1.el10_2 ✅ No regressions

🤖 This PR was automatically generated by GitHub Actions
Run ID: 32144535161

PlaidCat and others added 30 commits August 14, 2026 10:14
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 92270d0

This function is needed by fuse_uring.c to clean ring queues,
so make it non static. Especially in non-static mode the function
name 'end_requests' should be prefixed with fuse_

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Josef Bacik <josef@toxicpanda.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 92270d0)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 867d93d

Another preparation patch, as this function will be needed by
fuse/dev.c and fuse/dev_uring.c.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Josef Bacik <josef@toxicpanda.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 867d93d)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 88be7aa

These are needed by fuse-over-io-uring.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Josef Bacik <josef@toxicpanda.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 88be7aa)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 7ccd86b
upstream-diff | Context conflict on missing fs/fuse/fuse_i.h commit
	4174867 -virtiofs: use pages instead of pointer for kernel direct IO

This change sets up FUSE operations to always have headers in
args.in_args[0], even for opcodes without an actual header.
This step prepares for a clean separation of payload from headers,
initially it is used by fuse-over-io-uring.

For opcodes without a header, we use a zero-sized struct as a
placeholder. This approach:
- Keeps things consistent across all FUSE operations
- Will help with payload alignment later
- Avoids future issues when header sizes change

Op codes that already have an op code specific header do not
need modification.
Op codes that have neither payload nor op code headers
are not modified either (FUSE_READLINK and FUSE_DESTROY).
FUSE_BATCH_FORGET already has the header in the right place,
but is not using fuse_copy_args - as -over-uring is currently
not handling forgets it does not matter for now, but header
separation will later need special attention for that op code.

Correct the struct fuse_args->in_args array max size.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 7ccd86b)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 24fe962
upstream-diff | Context diff due to missing commit on fs/fuse/Makefile
	2b3933b - fuse: enable dynamic configuration of fuse max pages
			limit (FUSE_MAX_MAX_PAGES)
	Context difference due to future feature enabled earlier in git
	log order as well.

This adds basic support for ring SQEs (with opcode=IORING_OP_URING_CMD).
For now only FUSE_IO_URING_CMD_REGISTER is handled to register queue
entries.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 24fe962)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit d0f9c62

Move 'struct fuse_copy_state' and fuse_copy_* functions
to fuse_dev_i.h to make it available for fuse-io-uring.
'copy_out_args()' is renamed to 'fuse_copy_out_args'.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit d0f9c62)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit f773a7c

Add special fuse-io-uring into the fuse argument
copy handler.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit f773a7c)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 3821336

fuse-over-io-uring uses existing functions to find requests based
on their unique id - make these functions non-static.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 3821336)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit c090c8a

This adds support for fuse request completion through ring SQEs
(FUSE_URING_CMD_COMMIT_AND_FETCH handling). After committing
the ring entry it becomes available for new fuse requests.
Handling of requests through the ring (SQE/CQE handling)
is complete now.

Fuse request data are copied through the mmaped ring buffer,
there is no support for any zero copy yet.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit c090c8a)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 4a9bfb9

On teardown struct file_operations::uring_cmd requests
need to be completed by calling io_uring_cmd_done().
Not completing all ring entries would result in busy io-uring
tasks giving warning messages in intervals and unreleased
struct file.

Additionally the fuse connection and with that the ring can
only get released when all io-uring commands are completed.

Completion is done with ring entries that are
a) in waiting state for new fuse requests - io_uring_cmd_done
is needed

b) already in userspace - io_uring_cmd_done through teardown
is not needed, the request can just get released. If fuse server
is still active and commits such a ring entry, fuse_uring_cmd()
already checks if the connection is active and then complete the
io-uring itself with -ENOTCONN. I.e. special handling is not
needed.

This scheme is basically represented by the ring entry state
FRRS_WAIT and FRRS_USERSPACE.

Entries in state:
- FRRS_INIT: No action needed, do not contribute to
  ring->queue_refs yet
- All other states: Are currently processed by other tasks,
  async teardown is needed and it has to wait for the two
  states above. It could be also solved without an async
  teardown task, but would require additional if conditions
  in hot code paths. Also in my personal opinion the code
  looks cleaner with async teardown.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 4a9bfb9)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit ba74ba5

These functions are also needed by fuse-over-io-uring.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit ba74ba5)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit c2c9af9

This prepares queueing and sending foreground requests through
io-uring.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit c2c9af9)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 857b026

This prepares queueing and sending background requests through
io-uring.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 857b026)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit b6236c8

When the fuse-server terminates while the fuse-client or kernel
still has queued URING_CMDs, these commands retain references
to the struct file used by the fuse connection. This prevents
fuse_dev_release() from being invoked, resulting in a hung mount
point.

This patch addresses the issue by making queued URING_CMDs
cancelable, allowing fuse_dev_release() to proceed as expected
and preventing the mount point from hanging.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit b6236c8)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bernd@bsbernd.com>
commit 3393ff9
upstream-diff | Context conflict on missing fs/fuse/fuse_i.h commit
            4174867 -virtiofs: use pages instead of pointer for kernel direct IO

Avoid races and block request allocation until io-uring
queues are ready.

This is a especially important for background requests,
as bg request completion might cause lock order inversion
of the typical queue->lock and then fc->bg_lock

    fuse_request_end
       spin_lock(&fc->bg_lock);
       flush_bg_queue
         fuse_send_one
           fuse_uring_queue_fuse_req
           spin_lock(&queue->lock);

	Signed-off-by: Bernd Schubert <bernd@bsbernd.com>
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 3393ff9)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 786412a

All required parts are handled now, fuse-io-uring can
be enabled.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Pavel Begunkov <asml.silence@gmail.com> # io_uring
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 786412a)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 2d4fde5

The enable_uring module parameter allows administrators to enable/disable
io-uring support for FUSE at runtime. However, disabling io-uring while
connections already have it enabled can lead to an inconsistent state.

Fix this by keeping io-uring enabled on connections that were already using
it, even if the module parameter is later disabled. This ensures active
FUSE mounts continue to function correctly.

	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Luis Henriques <luis@igalia.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 2d4fde5)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit d9ecc77

There is a race condition leading to a kernel crash from a null
dereference when attemping to access fc->lock in
fuse_uring_create_queue(). fc may be NULL in the case where another
thread is creating the uring in fuse_uring_create() and has set
fc->ring but has not yet set ring->fc when fuse_uring_create_queue()
reads ring->fc. There is another race condition as well where in
fuse_uring_register(), ring->nr_queues may still be 0 and not yet set
to the new value when we compare qid against it.

This fix sets fc->ring only after ring->fc and ring->nr_queues have been
set, which guarantees now that ring->fc is a proper pointer when any
queues are created and ring->nr_queues reflects the right number of
queues if ring is not NULL. We must use smp_store_release() and
smp_load_acquire() semantics to ensure the ordering will remain correct
where fc->ring is assigned only after ring->fc and ring->nr_queues have
been assigned.

	Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Link: https://lore.kernel.org/r/20250318003028.3330599-1-joannelkoong@gmail.com
Fixes: 24fe962 ("fuse: {io-uring} Handle SQEs - register commands")
	Acked-by: Miklos Szeredi <mszeredi@redhat.com>
	Reviewed-by: Bernd Schubert <bschubert@ddn.com>
	Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit d9ecc77)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Luis Henriques <luis@igalia.com>
commit d550114

When mounting a user-space filesystem using io_uring, the initialization
of the rings is done separately in the server side.  If for some reason
(e.g. a server bug) this step is not performed it will be impossible to
unmount the filesystem if there are already requests waiting.

This issue is easily reproduced with the libfuse passthrough_ll example,
if the queue depth is set to '0' and a request is queued before trying to
unmount the filesystem.  When trying to force the unmount, fuse_abort_conn()
will try to wake up all tasks waiting in fc->blocked_waitq, but because the
rings were never initialized, fuse_uring_ready() will never return 'true'.

Fixes: 3393ff9 ("fuse: block request allocation until io-uring init is complete")
	Signed-off-by: Luis Henriques <luis@igalia.com>
Link: https://lore.kernel.org/r/20250306111218.13734-1-luis@igalia.com
	Acked-by: Miklos Szeredi <mszeredi@redhat.com>
	Reviewed-by: Bernd Schubert <bschubert@ddn.com>
	Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit d550114)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Luis Henriques <luis@igalia.com>
commit 841c7b8

Function fuse_uring_create() is used only from dev_uring.c and does not
need to be exposed in the header file.  Furthermore, it has the wrong
signature.

While there, also remove the 'struct fuse_ring' forward declaration.

	Signed-off-by: Luis Henriques <luis@igalia.com>
	Reviewed-by: Bernd Schubert <bschubert@ddn.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 841c7b8)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bschubert@ddn.com>
commit 09098e6

task-A (application) might be in request_wait_answer and
try to remove the request when it has FR_PENDING set.

task-B (a fuse-server io-uring task) might handle this
request with FUSE_IO_URING_CMD_COMMIT_AND_FETCH, when
fetching the next request and accessed the req from
the pending list in fuse_uring_ent_assign_req().
That code path was not protected by fiq->lock and so
might race with task-A.

For scaling reasons we better don't use fiq->lock, but
add a handler to remove canceled requests from the queue.

This also removes usage of fiq->lock from
fuse_uring_add_req_to_ring_ent() altogether, as it was
there just to protect against this race and incomplete.

Also added is a comment why FR_PENDING is not cleared.

Fixes: c090c8a ("fuse: Add io-uring sqe commit and fetch support")
	Cc: <stable@vger.kernel.org> # v6.14
	Reported-by: Joanne Koong <joannelkoong@gmail.com>
Closes: https://lore.kernel.org/all/CAJnrk1ZgHNb78dz-yfNTpxmW7wtT88A=m-zF0ZoLXKLUHRjNTw@mail.gmail.com/
	Signed-off-by: Bernd Schubert <bschubert@ddn.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 09098e6)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 2d06680

When the ring is allocated, it is kzalloc-ed. ring->queue_refs will
already be initialized to 0 by default. It does not need to be
atomically set to 0.

	Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
	Reviewed-by: Bernd Schubert <bschubert@ddn.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 2d06680)
	Signed-off-by: Jonathan Maple <jmaple@ciq.com>
jira SECO-478
cve CVE-2025-68791
RFE: FUSE_IO_URING
commit-author Cheng Ding <cding@ddn.com>
commit 6e0d7f7
upstream-diff |
            Context diffs from missing upstream type changes
            (bool write, is_uring = true) and surrounding declarations

Fix a possible reference count leak of payload pages during
fuse argument copies.

[Joanne: simplified error cleanup]

Fixes: c090c8a ("fuse: Add io-uring sqe commit and fetch support")
Cc: stable@vger.kernel.org # v6.14
Signed-off-by: Cheng Ding <cding@ddn.com>
Signed-off-by: Bernd Schubert <bschubert@ddn.com>
Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 6e0d7f7)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
cve CVE-2025-68805
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 95c39ee

When a request is terminated before it has been committed, the request
is not removed from the queue's list. This leaves a dangling list entry
that leads to list corruption and use-after-free issues.

Remove the request from the queue's list for terminated non-committed
requests.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Fixes: c090c8a ("fuse: Add io-uring sqe commit and fetch support")
Cc: stable@vger.kernel.org
Reviewed-by: Bernd Schubert <bschubert@ddn.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 95c39ee)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
cve CVE-2026-64264
RFE: FUSE_IO_URING
commit-author Chris Mason <clm@meta.com>
commit 3a0a8bc

copy_from_user() returns the number of bytes not copied as an unsigned
residual on failure (1..sizeof(struct fuse_out_header)). fuse_uring_commit
stores that residual in ssize_t err, sets req->out.h.error to -EFAULT,
then jumps to out: with err still holding the positive residual.

    err = copy_from_user(&req->out.h, &ent->headers->in_out,
                         sizeof(req->out.h));
    if (err) {
        req->out.h.error = -EFAULT;
        goto out;          /* err is the positive residual */
    }
    ...
    out:
        fuse_uring_req_end(ent, req, err);

fuse_uring_req_end() then runs

    if (error)
        req->out.h.error = error;

which overwrites the just-assigned -EFAULT with the positive residual.
FUSE callers such as fuse_simple_request() test err < 0 to detect
failure, so the positive value is interpreted as success and the
caller proceeds with an uninitialised or partial req->out.args.

Fix by assigning err = -EFAULT in the failure branch before jumping
to out, so fuse_uring_req_end() receives a negative errno and sets
req->out.h.error to -EFAULT.

Fixes: c090c8a ("fuse: Add io-uring sqe commit and fetch support")
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>
Reviewed-by: Bernd Schubert <bernd@bsbernd.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 3a0a8bc)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
cve CVE-2026-64588
RFE: FUSE_IO_URING
commit-author Chris Mason <clm@meta.com>
commit 46725a0

On weakly-ordered architectures, the store to fiq->ops can be
reordered past the store to ring->ready, allowing a CPU that sees
ring->ready == true via fuse_uring_ready() to dispatch requests
through a stale fiq->ops pointer. Upgrade the store to
smp_store_release() and the load in fuse_uring_ready() to
smp_load_acquire() so that the preceding WRITE_ONCE(fiq->ops, ...)
is visible to any CPU that observes ring->ready == true.

Additionally, fuse_uring_do_register() publishes ring->ready with
WRITE_ONCE() but the fast-path check reads it with a plain load.
This is a marked-vs-unmarked access that KCSAN will flag. Wrap it in
READ_ONCE() to mark it without adding unnecessary ordering.

Also wrap the fc->ring load in fuse_uring_ready() in READ_ONCE() to
prevent the compiler from reloading it between the NULL check and the
dereference.

Fixes: c2c9af9 ("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>
Reviewed-by: Bernd Schubert <bernd@bsbernd.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 46725a0)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
cve CVE-2026-68095
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 952b5d3
upstream-diff |
            fch->lock/fch->connected changed to fc->lock/fc->connected
            (fuse_chan struct not present in this kernel)

This fixes this race:
- thread a: io_uring_enter -> register sqe ->
  fuse_uring_create_ring_ent -> allocate ent but doesn't grab queue_ref
  yet
- thread b: fuse_conn_destroy() -> fuse_chan_abort() ->
  fuse_uring_abort() is a no-op due to queue ref being 0
- thread a: grabs the queue_ref, queue_ref is now 1, rest of
  fuse_uring_do_register() logic executes
- thread b: fuse_chan_abort() returns, fuse_chan_wait_aborted() now runs
  and calls
  "wait_event(ring->stop_waitq, atomic_read(&ring->queue_refs) == 0);"
The abort/unmount thread will hang indefinitely in unkillable state as
nothing will decrement queue_refs or wake stop_waitq, and the ring,
queue, and ent are leaked.

Fix this by checking fch->connected under fch->lock after the created
ent has grabbed a ref count on the queue. This ensures that in the
scenario above, it is guaranteed that we either release the queue ref
and wake up stop_waitq (in case fuse_chan_wait_aborted() is already
waiting) in fuse_uring_do_register() when we detect !fch->connected, or
if the connection is aborted after the check, it is guaranteed that the
async teardown worker will be running in the background cleaning up ents
and decrementing the ent's ref on the queue, which will unblock the
eventual queue and ring teardown.

Fixes: 24fe962 ("fuse: {io-uring} Handle SQEs - register commands")
Cc: stable@vger.kernel.org
Reviewed-by: Bernd Schubert <bernd@bsbernd.com>
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 952b5d3)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit c146284
upstream-diff |
            fch->lock/fch->connected changed to fc->lock/fc->connected
            in fuse_uring_do_register() already applied in 703224b.
            Only the fuse_uring_create() hunk is new.

Check fc->connected under fc->lock in fuse_uring_create() before
attaching a new ring. Without this, a race between fuse_uring_create()
and fuse_conn_destroy() can result in the ring, queue, and fpq.processing
table being created after fuse_uring_abort() has already run, leading
to unnecessary allocation and teardown. These are eventually cleaned up
by fuse_uring_destruct() but will linger until the process exits, even
with the connection aborted.

	Reviewed-by: Bernd Schubert <bernd@bsbernd.com>
	Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit c146284)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
cve CVE-2026-64263
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 198f45e
upstream-diff |
            io_uring_cmd_done() uses 4 args (res2=0) vs upstream 3 args.
            list_move used instead of list_move_tail.

fuse_uring_cancel() moves entries that are available (these have no reqs
attached) to the ent_in_userspace list. ent_list_request_expired()
checks the first entry on ent_in_userspace and dereferences
ent->fuse_req unconditionally, which will crash on a cancelled entry
that was moved to this list.

Fix this by freeing the entry and dropping queue_refs directly in
fuse_uring_cancel(). This is safe because cancel is the cancel handler
itself - after io_uring_cmd_done(), no more cancels will be dispatched
for this command, and teardown serializes with cancel via queue->lock.

Since cancel now decrements queue_refs, fuse_uring_abort() must no
longer gate fuse_uring_abort_end_requests() on queue_refs > 0, as
cancelled entries may have already dropped queue_refs while requests are
still queued. Remove the gate so abort always flushes requests and stops
queues.

	Reported-by: Heechan Kang <gganji11@naver.com>
	Tested-by: Heechan Kang <gganji11@naver.com>
	Reviewed-by: Bernd Schubert <bernd@bsbernd.com>
	Fixes: 4fea593 ("fuse: optimize over-io-uring request expiration check")
	Cc: stable@vger.kernel.org
	Suggested-by: Jian Huang Li <ali@ddn.com>
	Suggested-by: Horst Birthelmer <horst@birthelmer.de>
	Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 198f45e)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
cve CVE-2026-64262
RFE: FUSE_IO_URING
commit-author Chris Mason <clm@meta.com>
commit bea4fe9
upstream-diff |
            fuse_uring_send_in_task has different signature
            (missing io_tw_req/io_tw_token_t API in this kernel)
            io_uring_cmd_done() call corrected to pass 4 args
            (res2=0 was missing in upstream adaptation)

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: c2c9af9 ("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>
(cherry picked from commit bea4fe9)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
cve CVE-2026-64261
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bernd@bsbernd.com>
commit d351da7
upstream-diff |
            ring->fc used instead of ring->chan->conn

fuse_uring_async_stop_queues() might run when the last reference
on ring->queue_refs was already dropped.

In order to avoid an early destruction a reference on struct fuse_conn
is now taken before starting fuse_uring_async_stop_queues() and that
reference is only released when that delayed work queue terminates.

	Fixes: 4a9bfb9 ("fuse: {io-uring} Handle teardown of ring entries")
	Cc: stable@kernel.org # 6.14
	Reported-by: Berkant Koc <me@berkoc.com>
	Signed-off-by: Bernd Schubert <bernd@bsbernd.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit d351da7)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
…lock

jira SECO-478
cve CVE-2026-64260
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bernd@bsbernd.com>
commit b70a3ac
upstream-diff |
            ring->fc used instead of ring->chan->conn

There are several readers of queue->stopped that check the value
under lock, but fuse_uring_commit_fetch() did not and actually
the value was not set under the lock in fuse_uring_abort_end_requests()
either. Especially in fuse_uring_commit_fetch it is important
to check under a lock, because due to races 'struct fuse_req'
might be freed with fuse_request_end, but another thread/cpu
might already do teardown work.

	Cc: stable@kernel.org # 6.14
	Fixes: 4a9bfb9 ("fuse: {io-uring} Handle teardown of ring entries")
	Reported-by: Berkant Koc <me@berkoc.com>
	Reported-by: xlabai <xlabai@tencent.com>
	Signed-off-by: Bernd Schubert <bernd@bsbernd.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit b70a3ac)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
cve CVE-2026-64259
RFE: FUSE_IO_URING
commit-author Bernd Schubert <bernd@bsbernd.com>
commit 1efd3d4
upstream-diff |
            list_move used instead of list_move_tail and
            io_uring_cmd_done has extra arg (older API in this kernel)

Bad userspace might try to trick us and send commit SQEs request
unique / commit-id of requests that are not even send to
fuse-server (io_uring_cmd_done() not called) yet.

fuse_uring_commit_fetch() ends the fuse request when the ring entry
has a wrong state, but that could have caused a use-after-free
with the memcpy operations in fuse_uring_send_in_task().
In order to avoid such races the call of fuse_uring_add_to_pq()
is moved after the copy operations and just before completing
the io-uring request - malicious userspace cannot find the request
anymore until all prepration work in fuse-client/kernel is completed.

This also moves fuse_uring_add_to_pq() a bit up in the code to
avoid a forward declaration. Also not with a preparation commit,
to make it easier to back port to older kernels.

Reported-by: xlabai <xlabai@tencent.com>
Reported-by: Berkant Koc <me@berkoc.com>
Fixes: c090c8a ("fuse: Add io-uring sqe commit and fetch support")
Cc: stable@kernel.org # 6.14
Signed-off-by: Bernd Schubert <bernd@bsbernd.com>
Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 1efd3d4)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
…ULL deref

jira SECO-478
cve CVE-2026-64258
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 1c57a69

If a copy into the userspace ring buffer fails, a request will be
terminated and fuse_uring_req_end() will set ent->fuse_req to NULL but
it will leave the entry on ent_w_req_queue in FRRS_FUSE_REQ state. This
can lead to a NULL deref if the request expiration logic scans
ent_w_req_queue in the window before the entry is moved off it.

Fix this by taking the entry off ent_w_req_queue and changing its state
from FRRS_FUSE_REQ to FRRS_INVALID before terminating the request.

	Fixes: 4fea593 ("fuse: optimize over-io-uring request expiration check")
	Cc: stable@kernel.org
	Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 1c57a69)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Joanne Koong <joannelkoong@gmail.com>
commit 31da059
upstream-diff |
            fuse_copy_init uses int write vs bool write in this kernel

When a background request completes via the io_uring path, the
background queue gets flushed to dispatch pending background requests,
but this is done before the connection-level background counters
(fc->num_background, fc->active_background) are properly accounted,
which may reduce effective queue depth to one.

The connection-level counters are decremented in fuse_request_end(), but
flush_bg_queue() flushes the /dev/fuse path queue (fc->bg_queue), not
the io_uring per-queue bg one, which means pending uring background
requests on the queue are never dispatched in this path.

Fix this by accounting the connection-level background counters first
before flushing the queue's background queue. Since
fuse_request_bg_finish() clears FR_BACKGROUND, fuse_request_end() will
skip the background cleanup branch entirely, which avoids any
double-decrements; it will call the wake_up(&req->waitq) branch but this
is effectively a no-op as background requests have no waiters on
req->waitq.

Reviewed-by: Bernd Schubert <bernd@bsbernd.com>
Fixes: 857b026 ("fuse: Allow to queue bg requests through io-uring")
Cc: stable@vger.kernel.org
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 31da059)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Zhenghang Xiao <kipreyyy@gmail.com>
commit 7d87a5a

fuse_uring_commit_fetch() error path called fuse_request_end(req) without
clearing ent->fuse_req when fuse_ring_ent_set_commit() fails. The
still-pending fuse_uring_send_in_task() task-work later dereferences the
dangling pointer through fuse_uring_prepare_send(), causing a
use-after-free.

End the request with fuse_uring_req_end(), which handles all conditions
already.

Annotation/edition by Bernd: The UAF should be fixed by other means already
and actually has to be avoided that way.
Just checking for ent->fuse_req == NULL in fuse_uring_send_in_task()
would be prone to race conditions, because if malicious userspace
would commit requests that have passed the NULL check, but are
in doing args copy, it would still trigger a use-after-free.
Setting ent->fuse_req = NULL in fuse_uring_commit_fetch() still
makes sense, though.

	Reported-by: Shuvam Pandey <shuvampandey1@gmail.com>
	Reported-by: Berkant Koc <me@berkoc.com>
	Signed-off-by: Zhenghang Xiao <kipreyyy@gmail.com>
	Signed-off-by: Bernd Schubert <bernd@bsbernd.com>
	Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 7d87a5a)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING

Enable FUSE io-uring support in all configs that have both prerequisites
(CONFIG_FUSE_FS=m and CONFIG_IO_URING=y): x86_64, aarch64, ppc64le, and
s390x across all variants (debug, rt, 64k).

Skipped configs lacking prerequisites:
  - kernel-riscv64-*.config (no CONFIG_FUSE_FS or CONFIG_IO_URING)
  - kernel-s390x-zfcpdump-rhel.config (CONFIG_FUSE_FS is not set)

The feature is gated at runtime by the enable_uring module parameter
which defaults to disabled.

Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
…ectl

jira SECO-478
RFE: FUSE_IO_URING
commit-author Chen Linxuan <chenlinxuan@uniontech.com>
commit 1a7b137

This patch add a simple functional test for the 'abort' file in
fusectlfs (/sys/fs/fuse/connections/ID/abort). A simple fuse daemon
is added for testing.

	Signed-off-by: Chen Linxuan <chenlinxuan@uniontech.com>
	Acked-by: Shuah Khan <skhan@linuxfoundation.org>
	Reviewed-by: Amir Goldstein <amir73il@gmail.com>
	Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
(cherry picked from commit 1a7b137)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
On systems with only libfuse3-devel installed (no libfuse2-devel),
fuse_mnt.c fails to compile because fuse3 requires API version 30+.

Update fuse_mnt.c from FUSE API version 26 to 31:

  - getattr, truncate: add struct fuse_file_info * parameter
  - readdir: add enum fuse_readdir_flags parameter
  - filler calls: add flags argument

Also update the Makefile to try pkg-config fuse3 as a fallback when
pkg-config fuse is not available.

Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
jira SECO-478
RFE: FUSE_IO_URING
commit-author Amir Goldstein <amir73il@gmail.com>
commit 9acb102
upstream-diff |
            kselftest_harness.h include uses relative path
            (../../kselftest_harness.h) because commit e6fbd17
            ("selftests: complete kselftest include centralization")
            is not present in this tree.

A FUSE mount that does not negotiate FUSE_POSIX_ACL initialises every
inode with i_acl = i_default_acl = ACL_DONT_CACHE.  When a fresh stat
is needed (e.g. AT_STATX_FORCE_SYNC), fuse_update_get_attr() calls
forget_all_cached_acls() before issuing FUSE_GETATTR.  On an unfixed
kernel, __forget_cached_acl() replaces ACL_DONT_CACHE with
ACL_NOT_CACHED, inadvertently enabling the kernel ACL cache for that
inode.

This test validates the fix that preserves ACL_DONT_CACHE state in
forget_cached_acl().

	Signed-off-by: Amir Goldstein <amir73il@gmail.com>
	Signed-off-by: Christian Brauner <brauner@kernel.org>
(cherry picked from commit 9acb102)
	Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
Add a kselftest for the FUSE io-uring request dispatch path.  A
minimal in-memory FUSE daemon runs in a thread, negotiates
FUSE_OVER_IO_URING during FUSE_INIT, and handles requests through
FUSE_IO_URING_CMD_REGISTER / FUSE_IO_URING_CMD_COMMIT_AND_FETCH.
An atomic counter verifies requests are served through io_uring.

Test cases:
  - read_file: read and verify file content
  - write_and_readback: write data, read it back, compare
  - readdir: list directory, verify entries
  - stat_files: stat root and file, verify attributes
  - concurrent_io: 4 threads doing interleaved reads and writes
  - requests_via_uring: per-operation verification that read, write,
    readdir, and stat each produce io_uring requests
  - sustained_io: write 256KB in 4KB chunks, read back, verify pattern
  - crash_recovery: fork daemon, SIGKILL with active I/O, verify
    kernel health
  - abort_before_ring_ready: negotiate io_uring but never register
    entries, abort connection, verify no deadlock or leak

Tests SKIP when prerequisites are not met (no root, io_uring
disabled, enable_uring != Y).

Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
@ciq-kernel-automation ciq-kernel-automation Bot added the created-by-kernelci Tag PRs that were automatically created when a user branch was pushed to the repo (kernelCI) label Aug 18, 2026
@PlaidCat
PlaidCat requested a review from a team August 19, 2026 13:32
@bmastbergen

Copy link
Copy Markdown
Collaborator

Results from attached test script:

Warning: Permanently added '192.168.122.163' (ED25519) to the list of known hosts.
========================================
  FUSE io-uring test suite
  Wed Aug 19 08:21:22 PM UTC 2026
  Kernel: 6.12.0-bmastbergen_fuse_iouring_rlc-10_6.12.0-211.43.1.el10_+
========================================

--- [1/7] Checking prerequisites ---
  enable_uring = Y
  Checking RPM dependencies...
  All RPM dependencies present.
  Checking Python dependencies...
  All Python dependencies present.
  meson:      1.12.0
  ninja:      1.13.0.git.kitware.jobserver-pipe-1
  pytest:     pytest 9.1.1
  fusermount: /usr/bin/fusermount
  gcc:        gcc (GCC) 14.3.1 20251022 (Red Hat 14.3.1-4)
  All dependencies satisfied.

--- [2/7] Cloning libfuse (uring branch) ---
Existing clone found, updating...
Already on 'uring'
Your branch is up to date with 'origin/uring'.
HEAD is now at 10c5ff97 fuse_session_receive_buf: Fix the pipe buf size
libfuse HEAD: 10c5ff97 fuse_session_receive_buf: Fix the pipe buf size

--- [3/7] Building libfuse ---
Library dl found: YES
Library rt found: YES
Found pkg-config: YES (/usr/bin/pkg-config) 2.1.0
Found pkg-config: YES (/usr/bin/pkg-config) 2.1.0
Run-time dependency udev found: YES 257
C++ compiler for the host machine: c++ (gcc 14.3.1 "c++ (GCC) 14.3.1 20251022 (Red Hat 14.3.1-4)")
C++ linker for the host machine: c++ ld.bfd 2.41-63
Build targets in project: 30

Found ninja-1.13.0.git.kitware.jobserver-pipe-1 at /home/brett/.local/bin/ninja
[74/78] Linking target test/test_setattr
[75/78] Compiling C++ object example/memfs_ll.p/memfs_ll.cc.o
[76/78] Linking target example/memfs_ll
[77/78] Compiling C++ object example/passthrough_hp.p/passthrough_hp.cc.o
[78/78] Linking target example/passthrough_hp
Build complete.
fusermount3 set to setuid root.

--- [4/7] Running libfuse pytest suite (enable_uring=N baseline) ---
    The uring branch of libfuse negotiates io-uring by default;
    simple example daemons hang if enable_uring=Y because they
    never complete ring setup. Run baseline with uring OFF first.
============================= test session starts ==============================
platform linux -- Python 3.12.13, pytest-9.1.1, pluggy-1.6.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/brett/libfuse-uring-test/libfuse/build/test
configfile: pytest.ini
collecting ... collected 42 items / 4 deselected / 38 selected

test/test_examples.py::test_printcap <- util.py PASSED                   [  2%]
test/test_examples.py::test_hello[hello-options0-invoke_directly] PASSED [  5%]
test/test_examples.py::test_hello[hello-options0-invoke_mount_fuse] PASSED [  7%]
test/test_examples.py::test_hello[hello-options1-invoke_directly] PASSED [ 10%]
test/test_examples.py::test_hello[hello-options1-invoke_mount_fuse] PASSED [ 13%]
test/test_examples.py::test_hello[hello_ll-options0-invoke_directly] PASSED [ 15%]
test/test_examples.py::test_hello[hello_ll-options0-invoke_mount_fuse] PASSED [ 18%]
test/test_examples.py::test_hello[hello_ll-options1-invoke_directly] PASSED [ 21%]
test/test_examples.py::test_hello[hello_ll-options1-invoke_mount_fuse] PASSED [ 23%]
test/test_examples.py::test_passthrough[False-passthrough-False] PASSED  [ 26%]
test/test_examples.py::test_passthrough[False-passthrough-True] SKIPPED  [ 28%]
test/test_examples.py::test_passthrough[False-passthrough_plus-False] PASSED [ 31%]
test/test_examples.py::test_passthrough[False-passthrough_plus-True] SKIPPED [ 34%]
test/test_examples.py::test_passthrough[False-passthrough_fh-False] PASSED [ 36%]
test/test_examples.py::test_passthrough[False-passthrough_fh-True] SKIPPED [ 39%]
test/test_examples.py::test_passthrough[False-passthrough_ll-False] PASSED [ 42%]
test/test_examples.py::test_passthrough[False-passthrough_ll-True] PASSED [ 44%]
test/test_examples.py::test_passthrough[True-passthrough-False] PASSED   [ 47%]
test/test_examples.py::test_passthrough[True-passthrough-True] SKIPPED   [ 50%]
test/test_examples.py::test_passthrough[True-passthrough_plus-False] PASSED [ 52%]
test/test_examples.py::test_passthrough[True-passthrough_plus-True] SKIPPED [ 55%]
test/test_examples.py::test_passthrough[True-passthrough_fh-False] PASSED [ 57%]
test/test_examples.py::test_passthrough[True-passthrough_fh-True] SKIPPED [ 60%]
test/test_examples.py::test_passthrough[True-passthrough_ll-False] PASSED [ 63%]
test/test_examples.py::test_passthrough[True-passthrough_ll-True] PASSED [ 65%]
test/test_examples.py::test_passthrough_hp[False] PASSED                 [ 68%]
test/test_examples.py::test_passthrough_hp[True] PASSED                  [ 71%]
test/test_examples.py::test_ioctl PASSED                                 [ 73%]
test/test_examples.py::test_poll PASSED                                  [ 76%]
test/test_examples.py::test_null PASSED                                  [ 78%]
test/test_examples.py::test_notify_inval_entry[True-invalidate_entries] PASSED [ 81%]
test/test_examples.py::test_notify_inval_entry[True-expire_entries] PASSED [ 84%]
test/test_examples.py::test_notify_inval_entry[False-invalidate_entries] PASSED [ 86%]
test/test_examples.py::test_notify_inval_entry[False-expire_entries] PASSED [ 89%]
test/test_examples.py::test_dev_auto_unmount[root] PASSED                [ 92%]
test/test_examples.py::test_dev_auto_unmount[non_root] SKIPPED (needs to
run as non-root)                                                         [ 94%]
test/test_examples.py::test_cuse PASSED                                  [ 97%]
test/test_examples.py::test_release_unlink_race PASSED                   [100%]

=============================== warnings summary ===============================
../../../../../usr/local/lib/python3.12/site-packages/_pytest/config/__init__.py:1464
  /usr/local/lib/python3.12/site-packages/_pytest/config/__init__.py:1464: PytestConfigWarning: Unknown config option: maxfail
  
    self._warn_or_fail_if_strict(f"Unknown config option: {key}\n")

../../../../../usr/local/lib/python3.12/site-packages/_pytest/python.py:124
  /usr/local/lib/python3.12/site-packages/_pytest/python.py:124: PytestRemovedIn10Warning: Passing a non-Collection iterable to parametrize is deprecated.
  Test: test_examples.py::test_hello, argvalues type: chain
  Please convert to a list or tuple.
  See https://docs.pytest.org/en/stable/deprecations.html#parametrize-iterators
    metafunc.parametrize(*marker.args, **marker.kwargs, _param_mark=marker)

-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
=========================== short test summary info ============================
SKIPPED [6] test/test_examples.py:164: example does not support writeback caching
SKIPPED [1] test/test_examples.py:408: needs to run as non-root
=========== 31 passed, 7 skipped, 4 deselected, 2 warnings in 37.84s ===========

--- [5/7] Pytest summary ---
============================= test session starts ==============================
=============================== warnings summary ===============================
=========================== short test summary info ============================
=========== 31 passed, 7 skipped, 4 deselected, 2 warnings in 37.84s ===========

--- [6/7] Manual passthrough_hp + io-uring smoke test ---
Starting passthrough_hp with --uring...
  PASS: read file
  PASS: read content matches
  PASS: write+readback
  PASS: large file read
  PASS: readdir
  PASS: readdir subdir
  PASS: stat file
  PASS: stat dir
  PASS: readlink
  PASS: symlink read
  PASS: rename
  PASS: rename verify
  PASS: mkdir
  PASS: rmdir
  PASS: chmod
  PASS: truncate
  PASS: truncate verify
  PASS: unlink
  Running concurrent I/O...
  PASS: concurrent writes
  PASS: concurrent read 1
  PASS: concurrent read 2
  PASS: concurrent read 3
  PASS: concurrent read 4

  Smoke results: 23 passed, 0 failed

--- [7/7] Summary ---
Kernel:       6.12.0-bmastbergen_fuse_iouring_rlc-10_6.12.0-211.43.1.el10_+
enable_uring: Y
libfuse:      10c5ff97 fuse_session_receive_buf: Fix the pipe buf size
Logs:         /home/brett/libfuse-uring-test/logs/

Done. Wed Aug 19 08:22:11 PM UTC 2026

run-libfuse-uring-tests.sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

created-by-kernelci Tag PRs that were automatically created when a user branch was pushed to the repo (kernelCI)

Development

Successfully merging this pull request may close these issues.

2 participants