Add bdev_flush_by_dev() to submit page-cache writeback for a device identified by dev_t without requiring callers to hold a persistent device reference. A subsequent patch will use this helper to flush foreign bdev mappings. Signed-off-by: Julian Sun --- block/bdev.c | 24 ++++++++++++++++++++++++ include/linux/blkdev.h | 1 + 2 files changed, 25 insertions(+) diff --git a/block/bdev.c b/block/bdev.c index cd8323083740..da1fc56926fd 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -264,6 +264,30 @@ int sync_blockdev_nowait(struct block_device *bdev) } EXPORT_SYMBOL_GPL(sync_blockdev_nowait); +/** + * bdev_flush_by_dev - attempt writeback of a block device's page cache + * @dev: target block device number + * + * Skip closed devices or devices whose open_mutex is busy. + * May sleep while submitting writeback; does not wait for all I/O to complete. + */ +void bdev_flush_by_dev(dev_t dev) +{ + struct block_device *bdev; + + bdev = blkdev_get_no_open(dev, false); + if (!bdev) + return; + + /* Prevent the device from closing between the check and writeback. */ + if (mutex_trylock(&bdev->bd_disk->open_mutex)) { + if (atomic_read(&bdev->bd_openers)) + sync_blockdev_nowait(bdev); + mutex_unlock(&bdev->bd_disk->open_mutex); + } + blkdev_put_no_open(bdev); +} + /* * Write out and wait upon all the dirty data associated with a block * device via its mapping. Does not take the superblock lock. diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 4f7905c3412b..7a5f3e2f17d6 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1710,6 +1710,7 @@ void invalidate_bdev(struct block_device *bdev); int sync_blockdev(struct block_device *bdev); int sync_blockdev_range(struct block_device *bdev, loff_t lstart, loff_t lend); int sync_blockdev_nowait(struct block_device *bdev); +void bdev_flush_by_dev(dev_t dev); void sync_bdevs(bool wait); void bdev_statx(const struct path *path, struct kstat *stat, u32 request_mask); void printk_all_partitions(void); -- 2.39.5