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]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to