[PATCH 1/2] block: Add post_release() operation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add post_release() block device callback which allows release() block
device callback to schedule an extra cleanup operation while holding
disk->open_mutex and let post_release() callback synchronously perform
that operation without holding disk->open_mutex.

The loop driver needs this callback for synchronously performing autoclear
operation, for some userspace programs (e.g. xfstest) depend on that the
autoclear operation already completes by the moment lo_release() from
close() returns to userspace and immediately call umount() of a partition
containing a backing file which the autoclear operation will close(), but
temporarily dropping disk->open_mutex inside lo_release() in order to avoid
circular locking dependency is considered as a bad approach.

Note that unlike release() callback, post_release() callback is called
every time blkdev_put() is called. That is, the release() callback is
responsible for making it possible for post_release() callback to tell
whether post_release() callback has something to do.

Reported-by: kernel test robot <oliver.sang@xxxxxxxxx>
Fixes: 322c4293ecc58110 ("loop: make autoclear operation asynchronous")
Signed-off-by: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx>
---
 block/bdev.c           | 2 ++
 include/linux/blkdev.h | 5 +++++
 2 files changed, 7 insertions(+)

diff --git a/block/bdev.c b/block/bdev.c
index 8bf93a19041b..0cb638d81a27 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -948,6 +948,8 @@ void blkdev_put(struct block_device *bdev, fmode_t mode)
 	else
 		blkdev_put_whole(bdev, mode);
 	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);
 	blkdev_put_no_open(bdev);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index c80cfaefc0a8..b252b1d87471 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -1227,6 +1227,11 @@ struct block_device_operations {
 	 * driver.
 	 */
 	int (*alternative_gpt_sector)(struct gendisk *disk, sector_t *sector);
+	/*
+	 * Special callback for doing post-release callback without
+	 * disk->open_mutex held. Used by loop driver.
+	 */
+	void (*post_release)(struct gendisk *disk);
 };
 
 #ifdef CONFIG_COMPAT
-- 
2.32.0




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux