Re: [PATCH 6/9] block: add a mark_dead holder operation

Jan Kara
2023-05-08T13:01:39Z

On Fri 05-05-23 13:51:29, Christoph Hellwig wrote:
> 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: Christoph Hellwig <hch@lst.de>

One question below:

> ---
> block/genhd.c | 24 ++++++++++++++++++++++++
> include/linux/blkdev.h | 1 +
> 2 files changed, 25 insertions(+)
>
> diff --git a/block/genhd.c b/block/genhd.c
> index d1c673b967c254..af97a4ef1e926c 100644
> --- a/block/genhd.c
> +++ b/block/genhd.c
> @@ -575,6 +575,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
> @@ -602,6 +624,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);

Hum, but this gets called from del_gendisk() after blk_drop_partitions()
happens. So how is this going to be able to iterate anything?

Honza

--
Jan Kara <jack@suse.com>
SUSE Labs, CR