From: He Zhe <[email protected]>
This reverts commit f0b870df80bc70dad432fd0c142bb709a49964f5.
Adjust context of block/ioctl.c
---
block/ioctl.c | 35 ++++++++++++++++++++++++++++-----
drivers/block/loop.c | 13 +++++-------
drivers/s390/block/dasd_genhd.c | 4 +---
fs/block_dev.c | 7 -------
include/linux/fs.h | 2 ++
5 files changed, 38 insertions(+), 23 deletions(-)
diff --git a/block/ioctl.c b/block/ioctl.c
index 5de98b97af2a..775023548cb7 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -155,21 +155,46 @@ static int blkpg_ioctl(struct block_device *bdev, struct
blkpg_ioctl_arg __user
}
}
-static int blkdev_reread_part(struct block_device *bdev)
+/*
+ * This is an exported API for the block driver, and will not
+ * acquire bd_mutex. This API should be used in case that
+ * caller has held bd_mutex already.
+ */
+int __blkdev_reread_part(struct block_device *bdev)
{
- int ret;
-
if (!disk_part_scan_enabled(bdev->bd_disk) || bdev != bdev->bd_contains)
return -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
+ lockdep_assert_held(&bdev->bd_mutex);
+
+ return bdev_disk_changed(bdev, false);
+}
+EXPORT_SYMBOL(__blkdev_reread_part);
+
+/*
+ * This is an exported API for the block driver, and will
+ * try to acquire bd_mutex. If bd_mutex has been held already
+ * in current context, please call __blkdev_reread_part().
+ *
+ * Make sure the held locks in current context aren't required
+ * in open()/close() handler and I/O path for avoiding ABBA deadlock:
+ * - bd_mutex is held before calling block driver's open/close
+ * handler
+ * - reading partition table may submit I/O to the block device
+ */
+int blkdev_reread_part(struct block_device *bdev)
+{
+ int res;
+
mutex_lock(&bdev->bd_mutex);
- ret = bdev_disk_changed(bdev, false);
+ res = __blkdev_reread_part(bdev);
mutex_unlock(&bdev->bd_mutex);
- return ret;
+ return res;
}
+EXPORT_SYMBOL(blkdev_reread_part);
static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
unsigned long arg, unsigned long flags)
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 739b372a5112..ef6e251857c8 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -640,9 +640,7 @@ static void loop_reread_partitions(struct loop_device *lo,
{
int rc;
- mutex_lock(&bdev->bd_mutex);
- rc = bdev_disk_changed(bdev, false);
- mutex_unlock(&bdev->bd_mutex);
+ rc = blkdev_reread_part(bdev);
if (rc)
pr_warn("%s: partition scan of loop%d (%s) failed (rc=%d)\n",
__func__, lo->lo_number, lo->lo_file_name, rc);
@@ -1166,11 +1164,10 @@ static int __loop_clr_fd(struct loop_device *lo, bool
release)
* must be at least one and it can only become zero when the
* current holder is released.
*/
- if (!release)
- mutex_lock(&bdev->bd_mutex);
- err = bdev_disk_changed(bdev, false);
- if (!release)
- mutex_unlock(&bdev->bd_mutex);
+ if (release)
+ err = __blkdev_reread_part(bdev);
+ else
+ err = blkdev_reread_part(bdev);
if (err)
pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
__func__, lo_number, err);
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index 7d079154f849..5542d9eadfe0 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -116,9 +116,7 @@ int dasd_scan_partitions(struct dasd_block *block)
return -ENODEV;
}
- mutex_lock(&bdev->bd_mutex);
- rc = bdev_disk_changed(bdev, false);
- mutex_unlock(&bdev->bd_mutex);
+ rc = blkdev_reread_part(bdev);
if (rc)
DBF_DEV_EVENT(DBF_ERR, block->base,
"scan partitions error, rc %d", rc);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 387b64665dc2..6f335fc1501d 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1513,8 +1513,6 @@ int bdev_disk_changed(struct block_device *bdev, bool
invalidate)
struct gendisk *disk = bdev->bd_disk;
int ret;
- lockdep_assert_held(&bdev->bd_mutex);
-
rescan:
ret = blk_drop_partitions(disk, bdev);
if (ret)
@@ -1542,11 +1540,6 @@ int bdev_disk_changed(struct block_device *bdev, bool
invalidate)
return ret;
}
-/*
- * Only exported for for loop and dasd for historic reasons. Don't use in new
- * code!
- */
-EXPORT_SYMBOL_GPL(bdev_disk_changed);
/*
* bd_mutex locking:
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 98e0349adb52..30676ca9a258 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2639,6 +2639,8 @@ extern void bd_finish_claiming(struct block_device *bdev,
extern void bd_abort_claiming(struct block_device *bdev,
struct block_device *whole, void *holder);
extern void blkdev_put(struct block_device *bdev, fmode_t mode);
+extern int __blkdev_reread_part(struct block_device *bdev);
+extern int blkdev_reread_part(struct block_device *bdev);
#ifdef CONFIG_SYSFS
extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk
*disk);
--
2.24.1
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#8444):
https://lists.yoctoproject.org/g/linux-yocto/message/8444
Mute This Topic: https://lists.yoctoproject.org/mt/71728977/21656
Group Owner: [email protected]
Unsubscribe: https://lists.yoctoproject.org/g/linux-yocto/unsub
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-