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

block: move bd_mutex to struct gendisk



Replace the per-block device bd_mutex with a per-gendisk open_mutex,
thus simplifying locking wherever we deal with partitions.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarMing Lei <ming.lei@redhat.com>
Acked-by: default avatarRoger Pau Monné <roger.pau@citrix.com>
Link: https://lore.kernel.org/r/20210525061301.2242282-4-hch@lst.de


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 210a6d75
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -480,7 +480,7 @@ prototypes::
locking rules:

======================= ===================
ops			bd_mutex
ops			open_mutex
======================= ===================
open:			yes
release:		yes
+4 −3
Original line number Diff line number Diff line
@@ -591,10 +591,10 @@ void del_gendisk(struct gendisk *disk)
	blk_integrity_del(disk);
	disk_del_events(disk);

	mutex_lock(&disk->part0->bd_mutex);
	mutex_lock(&disk->open_mutex);
	disk->flags &= ~GENHD_FL_UP;
	blk_drop_partitions(disk);
	mutex_unlock(&disk->part0->bd_mutex);
	mutex_unlock(&disk->open_mutex);

	fsync_bdev(disk->part0);
	__invalidate_device(disk->part0, true);
@@ -1273,6 +1273,7 @@ struct gendisk *__alloc_disk_node(int minors, int node_id)
		goto out_free_disk;

	disk->node_id = node_id;
	mutex_init(&disk->open_mutex);
	xa_init(&disk->part_tbl);
	if (xa_insert(&disk->part_tbl, 0, disk->part0, GFP_KERNEL))
		goto out_destroy_part_tbl;
@@ -1525,7 +1526,7 @@ void disk_unblock_events(struct gendisk *disk)
 * doesn't clear the events from @disk->ev.
 *
 * CONTEXT:
 * If @mask is non-zero must be called with bdev->bd_mutex held.
 * If @mask is non-zero must be called with disk->open_mutex held.
 */
void disk_flush_events(struct gendisk *disk, unsigned int mask)
{
+10 −14
Original line number Diff line number Diff line
@@ -283,7 +283,7 @@ struct device_type part_type = {
};

/*
 * Must be called either with bd_mutex held, before a disk can be opened or
 * Must be called either with open_mutex held, before a disk can be opened or
 * after all disk users are gone.
 */
static void delete_partition(struct block_device *part)
@@ -312,7 +312,7 @@ static ssize_t whole_disk_show(struct device *dev,
static DEVICE_ATTR(whole_disk, 0444, whole_disk_show, NULL);

/*
 * Must be called either with bd_mutex held, before a disk can be opened or
 * Must be called either with open_mutex held, before a disk can be opened or
 * after all disk users are gone.
 */
static struct block_device *add_partition(struct gendisk *disk, int partno,
@@ -453,15 +453,15 @@ int bdev_add_partition(struct block_device *bdev, int partno,
{
	struct block_device *part;

	mutex_lock(&bdev->bd_mutex);
	mutex_lock(&bdev->bd_disk->open_mutex);
	if (partition_overlaps(bdev->bd_disk, start, length, -1)) {
		mutex_unlock(&bdev->bd_mutex);
		mutex_unlock(&bdev->bd_disk->open_mutex);
		return -EBUSY;
	}

	part = add_partition(bdev->bd_disk, partno, start, length,
			ADDPART_FLAG_NONE, NULL);
	mutex_unlock(&bdev->bd_mutex);
	mutex_unlock(&bdev->bd_disk->open_mutex);
	return PTR_ERR_OR_ZERO(part);
}

@@ -474,8 +474,7 @@ int bdev_del_partition(struct block_device *bdev, int partno)
	if (!part)
		return -ENXIO;

	mutex_lock(&part->bd_mutex);
	mutex_lock_nested(&bdev->bd_mutex, 1);
	mutex_lock(&bdev->bd_disk->open_mutex);

	ret = -EBUSY;
	if (part->bd_openers)
@@ -484,8 +483,7 @@ int bdev_del_partition(struct block_device *bdev, int partno)
	delete_partition(part);
	ret = 0;
out_unlock:
	mutex_unlock(&bdev->bd_mutex);
	mutex_unlock(&part->bd_mutex);
	mutex_unlock(&bdev->bd_disk->open_mutex);
	bdput(part);
	return ret;
}
@@ -500,8 +498,7 @@ int bdev_resize_partition(struct block_device *bdev, int partno,
	if (!part)
		return -ENXIO;

	mutex_lock(&part->bd_mutex);
	mutex_lock_nested(&bdev->bd_mutex, 1);
	mutex_lock(&bdev->bd_disk->open_mutex);
	ret = -EINVAL;
	if (start != part->bd_start_sect)
		goto out_unlock;
@@ -514,8 +511,7 @@ int bdev_resize_partition(struct block_device *bdev, int partno,

	ret = 0;
out_unlock:
	mutex_unlock(&part->bd_mutex);
	mutex_unlock(&bdev->bd_mutex);
	mutex_unlock(&bdev->bd_disk->open_mutex);
	bdput(part);
	return ret;
}
@@ -541,7 +537,7 @@ void blk_drop_partitions(struct gendisk *disk)
	struct block_device *part;
	unsigned long idx;

	lockdep_assert_held(&disk->part0->bd_mutex);
	lockdep_assert_held(&disk->open_mutex);

	xa_for_each_start(&disk->part_tbl, idx, part, 1) {
		if (!bdgrab(part))
+7 −7
Original line number Diff line number Diff line
@@ -652,9 +652,9 @@ static void loop_reread_partitions(struct loop_device *lo,
{
	int rc;

	mutex_lock(&bdev->bd_mutex);
	mutex_lock(&bdev->bd_disk->open_mutex);
	rc = bdev_disk_changed(bdev, false);
	mutex_unlock(&bdev->bd_mutex);
	mutex_unlock(&bdev->bd_disk->open_mutex);
	if (rc)
		pr_warn("%s: partition scan of loop%d (%s) failed (rc=%d)\n",
			__func__, lo->lo_number, lo->lo_file_name, rc);
@@ -747,7 +747,7 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev,
	mutex_unlock(&lo->lo_mutex);
	/*
	 * We must drop file reference outside of lo_mutex as dropping
	 * the file ref can take bd_mutex which creates circular locking
	 * the file ref can take open_mutex which creates circular locking
	 * dependency.
	 */
	fput(old_file);
@@ -1260,7 +1260,7 @@ static int __loop_clr_fd(struct loop_device *lo, bool release)
	mutex_unlock(&lo->lo_mutex);
	if (partscan) {
		/*
		 * bd_mutex has been held already in release path, so don't
		 * open_mutex has been held already in release path, so don't
		 * acquire it if this function is called in such case.
		 *
		 * If the reread partition isn't from release path, lo_refcnt
@@ -1268,10 +1268,10 @@ static int __loop_clr_fd(struct loop_device *lo, bool release)
		 * current holder is released.
		 */
		if (!release)
			mutex_lock(&bdev->bd_mutex);
			mutex_lock(&bdev->bd_disk->open_mutex);
		err = bdev_disk_changed(bdev, false);
		if (!release)
			mutex_unlock(&bdev->bd_mutex);
			mutex_unlock(&bdev->bd_disk->open_mutex);
		if (err)
			pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
				__func__, lo_number, err);
@@ -1298,7 +1298,7 @@ static int __loop_clr_fd(struct loop_device *lo, bool release)
	/*
	 * Need not hold lo_mutex to fput backing file. Calling fput holding
	 * lo_mutex triggers a circular lock dependency possibility warning as
	 * fput can take bd_mutex which is usually taken before lo_mutex.
	 * fput can take open_mutex which is usually taken before lo_mutex.
	 */
	if (filp)
		fput(filp);
+4 −4
Original line number Diff line number Diff line
@@ -2163,7 +2163,7 @@ static void blkfront_closing(struct blkfront_info *info)
		return;
	}

	mutex_lock(&bdev->bd_mutex);
	mutex_lock(&bdev->bd_disk->open_mutex);

	if (bdev->bd_openers) {
		xenbus_dev_error(xbdev, -EBUSY,
@@ -2174,7 +2174,7 @@ static void blkfront_closing(struct blkfront_info *info)
		xenbus_frontend_closed(xbdev);
	}

	mutex_unlock(&bdev->bd_mutex);
	mutex_unlock(&bdev->bd_disk->open_mutex);
	bdput(bdev);
}

@@ -2531,7 +2531,7 @@ static int blkfront_remove(struct xenbus_device *xbdev)
	 * isn't closed yet, we let release take care of it.
	 */

	mutex_lock(&bdev->bd_mutex);
	mutex_lock(&disk->open_mutex);
	info = disk->private_data;

	dev_warn(disk_to_dev(disk),
@@ -2546,7 +2546,7 @@ static int blkfront_remove(struct xenbus_device *xbdev)
		mutex_unlock(&blkfront_mutex);
	}

	mutex_unlock(&bdev->bd_mutex);
	mutex_unlock(&disk->open_mutex);
	bdput(bdev);

	return 0;
Loading