On Sat, Feb 07, 2026 at 08:08:59PM +0800, Brian Song wrote:
> When a termination signal is received, the storage-export-daemon stops
> the export, exits the main loop (main_loop_wait), and begins resource
> cleanup. However, some FUSE_IO_URING_CMD_COMMIT_AND_FETCH SQEs may
> remain pending in the kernel, waiting for incoming FUSE requests.
> 
> Currently, there is no way to manually cancel these pending CQEs in the
> kernel. As a result, after export termination, the related data
> structures might be deleted before the pending CQEs return, causing the
> CQE handler to be invoked after it has been freed, which may lead to a
> segfault.
> 
> As a workaround, when submitting an SQE to the kernel, we increment the
> block reference (blk_exp_ref) to prevent the CQE handler from being
> deleted during export termination. Once the CQE is received, we
> decrement the reference (blk_exp_unref).
> 
> However, this introduces a new issue: if no new FUSE requests arrive,
> the pending SQEs held by the kernel will never complete. Consequently,
> the export reference count never drops to zero, preventing the export
> from shutting down cleanly.
> 
> To resolve this, we schedule a Bottom Half (BH) for each FUSE queue
> during the export shutdown phase. The BH closes the fuse_fd to prevent
> race conditions, while the session is unmounted during the remainder of
> the shutdown sequence. This explicitly aborts all pending SQEs in the
> kernel, forcing the corresponding CQEs to return. This triggers the
> release of held references, allowing the export to be freed safely.
> 
> Suggested-by: Kevin Wolf <[email protected]>
> Suggested-by: Stefan Hajnoczi <[email protected]>
> Signed-off-by: Brian Song <[email protected]>
> ---
>  block/export/fuse.c | 100 +++++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 90 insertions(+), 10 deletions(-)

Reviewed-by: Stefan Hajnoczi <[email protected]>

Attachment: signature.asc
Description: PGP signature

Reply via email to