Commit f55e017c authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

block: add a mark_dead holder operation



Add a mark_dead method to blk_holder_ops that is called from blk_mark_disk_dead
to notify the holder that the block device it is using has been marked dead.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
Acked-by: default avatarChristian Brauner <brauner@kernel.org>
Acked-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
Link: https://lore.kernel.org/r/20230601094459.1350643-11-hch@lst.de


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 0718afd4
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -565,6 +565,28 @@ int __must_check device_add_disk(struct device *parent, struct gendisk *disk,
}
EXPORT_SYMBOL(device_add_disk);

static void blk_report_disk_dead(struct gendisk *disk)
{
	struct block_device *bdev;
	unsigned long idx;

	rcu_read_lock();
	xa_for_each(&disk->part_tbl, idx, bdev) {
		if (!kobject_get_unless_zero(&bdev->bd_device.kobj))
			continue;
		rcu_read_unlock();

		mutex_lock(&bdev->bd_holder_lock);
		if (bdev->bd_holder_ops && bdev->bd_holder_ops->mark_dead)
			bdev->bd_holder_ops->mark_dead(bdev);
		mutex_unlock(&bdev->bd_holder_lock);

		put_device(&bdev->bd_device);
		rcu_read_lock();
	}
	rcu_read_unlock();
}

/**
 * blk_mark_disk_dead - mark a disk as dead
 * @disk: disk to mark as dead
@@ -592,6 +614,8 @@ void blk_mark_disk_dead(struct gendisk *disk)
	 * Prevent new I/O from crossing bio_queue_enter().
	 */
	blk_queue_start_drain(disk->queue);

	blk_report_disk_dead(disk);
}
EXPORT_SYMBOL_GPL(blk_mark_disk_dead);

+1 −0
Original line number Diff line number Diff line
@@ -1471,6 +1471,7 @@ void blkdev_show(struct seq_file *seqf, off_t offset);
#endif

struct blk_holder_ops {
	void (*mark_dead)(struct block_device *bdev);
};

struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder,