diff options
author | Yu Kuai <yukuai3@huawei.com> | 2022-11-15 22:10:53 +0800 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2022-11-16 15:19:56 -0700 |
commit | 3b3449c1e6c3fe19f62607ff4f353f8bb82d5c4e (patch) | |
tree | 2582441eb9c850073343c9726fbeb1dde9e6f007 /block | |
parent | 62f535e1f061b4c2cc76061b6b59af9f9335ee34 (diff) | |
download | linux-stable-3b3449c1e6c3fe19f62607ff4f353f8bb82d5c4e.tar.gz linux-stable-3b3449c1e6c3fe19f62607ff4f353f8bb82d5c4e.tar.bz2 linux-stable-3b3449c1e6c3fe19f62607ff4f353f8bb82d5c4e.zip |
block: store the holder kobject in bd_holder_disk
We hold a reference to the holder kobject for each bd_holder_disk,
so to make the code a bit more robust, use a reference to it instead
of the block_device. As long as no one clears ->bd_holder_dir in
before freeing the disk, this isn't strictly required, but it does
make the code more clear and more robust.
Orignally-From: Christoph Hellwig <hch@lst.de>
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20221115141054.1051801-10-yukuai1@huaweicloud.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r-- | block/holder.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/block/holder.c b/block/holder.c index c8e462053f49..3332142bb867 100644 --- a/block/holder.c +++ b/block/holder.c @@ -4,7 +4,7 @@ struct bd_holder_disk { struct list_head list; - struct block_device *bdev; + struct kobject *holder_dir; int refcnt; }; @@ -14,7 +14,7 @@ static struct bd_holder_disk *bd_find_holder_disk(struct block_device *bdev, struct bd_holder_disk *holder; list_for_each_entry(holder, &disk->slave_bdevs, list) - if (holder->bdev == bdev) + if (holder->holder_dir == bdev->bd_holder_dir) return holder; return NULL; } @@ -94,8 +94,9 @@ int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk) } INIT_LIST_HEAD(&holder->list); - holder->bdev = bdev; holder->refcnt = 1; + holder->holder_dir = bdev->bd_holder_dir; + ret = add_symlink(disk->slave_dir, bdev_kobj(bdev)); if (ret) goto out_free_holder; @@ -140,8 +141,8 @@ void bd_unlink_disk_holder(struct block_device *bdev, struct gendisk *disk) holder = bd_find_holder_disk(bdev, disk); if (!WARN_ON_ONCE(holder == NULL) && !--holder->refcnt) { del_symlink(disk->slave_dir, bdev_kobj(bdev)); - del_symlink(bdev->bd_holder_dir, &disk_to_dev(disk)->kobj); - kobject_put(bdev->bd_holder_dir); + del_symlink(holder->holder_dir, &disk_to_dev(disk)->kobj); + kobject_put(holder->holder_dir); list_del_init(&holder->list); kfree(holder); } |