Rust for Linux List
 help / color / mirror / Atom feed
* [PATCH 1/2] block: Add post_release() operation
@ 2026-09-09 10:48 Tetsuo Handa
  2026-09-09 10:49 ` [PATCH 2/2] loop: Perform __loop_clr_fd() after disk->open_mutex is dropped Tetsuo Handa
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Tetsuo Handa @ 2026-09-09 10:48 UTC (permalink / raw)
  To: Jens Axboe, Bart Van Assche, Christoph Hellwig
  Cc: Al Viro, Andrew Morton, Brian Foster, Damien Le Moal,
	Hillf Danton, Markus Elfring, Ming Lei, Qu Wenruo, Tao Cui,
	kernel test robot, linux-block, rust-for-linux

Add post_release() block device operation which provides a hook for
performing synchronous cleanup without disk->open_mutex held, which is
needed by the loop devices.

Real-world container engines, test suites, and system utilities rely on
fput() from __loop_clr_fd() being completed when lo_release() returns.
But changes which went to the v7.1 merge window broke an assumption that
there is no outstanding I/O when __loop_clr_fd() is called, causing NULL
pointer dereference problem in lo_rw_aio().

In order to fix this regression, we want to allow __loop_clr_fd() to flush
outstanding I/O. But calling drain_workqueue() from __loop_clr_fd() with
disk->open_mutex held causes lockdep warnings. We need a mechanism which
can flush outstanding I/O without disk->open_mutex held.

This post_release() operation is intended for performing only idempotent
actions such as flush_work(), for nothing prevents multiple threads from
concurrently calling this operation. That is, the loop device schedules
a work_struct for calling __loop_clr_fd() from lo_release() where
disk->open_mutex is held, and waits for completion of that work_struct
using post_release() operation where disk->open_mutex is not held.

Also, this post_release() operation is called from only bdev_release()
path. This is because loop_configure() is not yet called (there is nothing
to clear) if something went wrong between an initialization lo_open() and
an error-unwinding lo_release() within the bdev_open() path.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
 block/bdev.c                     | 2 ++
 include/linux/blkdev.h           | 6 ++++++
 rust/kernel/block/mq/gen_disk.rs | 1 +
 3 files changed, 9 insertions(+)

diff --git a/block/bdev.c b/block/bdev.c
index cd8323083740..7ce5acaacf43 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -1188,6 +1188,8 @@ void bdev_release(struct file *bdev_file)
 	else
 		blkdev_put_whole(bdev);
 	mutex_unlock(&disk->open_mutex);
+	if (bdev->bd_disk->fops->post_release)
+		bdev->bd_disk->fops->post_release(bdev->bd_disk);
 
 	module_put(disk->fops->owner);
 put_no_open:
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 4f7905c3412b..f05dba1b5962 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1605,6 +1605,12 @@ struct block_device_operations {
 	 * driver.
 	 */
 	int (*alternative_gpt_sector)(struct gendisk *disk, sector_t *sector);
+	/*
+	 * Called after disk->open_mutex is released in the bdev_release() path.
+	 * Used by loop devices that need to perform synchronization without
+	 * holding disk->open_mutex. This operation has to be idempotent.
+	 */
+	void (*post_release)(struct gendisk *disk);
 };
 
 #ifdef CONFIG_COMPAT
diff --git a/rust/kernel/block/mq/gen_disk.rs b/rust/kernel/block/mq/gen_disk.rs
index fc97dd873974..2ff77ef49781 100644
--- a/rust/kernel/block/mq/gen_disk.rs
+++ b/rust/kernel/block/mq/gen_disk.rs
@@ -129,6 +129,7 @@ pub fn build<T: Operations>(
             submit_bio: None,
             open: None,
             release: None,
+            post_release: None,
             ioctl: None,
             compat_ioctl: None,
             check_events: None,
-- 
2.55.0

^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2026-09-12  1:44 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-09 10:48 [PATCH 1/2] block: Add post_release() operation Tetsuo Handa
2026-09-09 10:49 ` [PATCH 2/2] loop: Perform __loop_clr_fd() after disk->open_mutex is dropped Tetsuo Handa
2026-09-09 19:33   ` Bart Van Assche
2026-09-10  9:44     ` Tetsuo Handa
2026-09-11 20:03       ` Bart Van Assche
2026-09-11 22:18         ` Tetsuo Handa
2026-09-12  1:02           ` Bart Van Assche
2026-09-12  1:22             ` Tetsuo Handa
2026-09-10 11:53 ` [PATCH 1/2] block: Add post_release() operation Gary Guo
2026-09-10 12:14   ` Tetsuo Handa
2026-09-11 19:54 ` Bart Van Assche
2026-09-11 22:34   ` Tetsuo Handa
2026-09-12  0:31     ` Bart Van Assche
2026-09-12  1:43       ` Tetsuo Handa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox