summaryrefslogtreecommitdiffstats
path: root/block/holder.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2021-08-20 11:49:29 +0200
committerJens Axboe <axboe@kernel.dk>2021-08-21 05:14:26 +0200
commit759e0fd4b67766c96b33a114bba0c7d7521fecd0 (patch)
treeec34c2e6ee2d2ed804682780b5efb8cebf3e86bf /block/holder.c
parentblock: fix default IO priority handling (diff)
downloadlinux-759e0fd4b67766c96b33a114bba0c7d7521fecd0.tar.xz
linux-759e0fd4b67766c96b33a114bba0c7d7521fecd0.zip
block: add back the bd_holder_dir reference in bd_link_disk_holder
This essentially reverts "block: remove the extra kobject reference in bd_link_disk_holder". That commit dropped the extra reference because the condition in the comment can't be true. But it turns out that comment did not actually describe the problematic situation, so add back the extra reference and document it properly. Fixes: fbd9a39542ec ("block: remove the extra kobject reference in bd_link_disk_holder") Reported-by: Tushar Sugandhi <tusharsu@linux.microsoft.com> Reviewed-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/holder.c')
-rw-r--r--block/holder.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/block/holder.c b/block/holder.c
index 4568cc4f6827..9dc084182337 100644
--- a/block/holder.c
+++ b/block/holder.c
@@ -106,6 +106,12 @@ int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk)
}
list_add(&holder->list, &disk->slave_bdevs);
+ /*
+ * del_gendisk drops the initial reference to bd_holder_dir, so we need
+ * to keep our own here to allow for cleanup past that point.
+ */
+ kobject_get(bdev->bd_holder_dir);
+
out_unlock:
mutex_unlock(&disk->open_mutex);
return ret;
@@ -138,6 +144,7 @@ void bd_unlink_disk_holder(struct block_device *bdev, struct gendisk *disk)
if (!WARN_ON_ONCE(holder == NULL) && !--holder->refcnt) {
if (disk->slave_dir)
__unlink_disk_holder(bdev, disk);
+ kobject_put(bdev->bd_holder_dir);
list_del_init(&holder->list);
kfree(holder);
}