summaryrefslogtreecommitdiff
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c32
1 files changed, 14 insertions, 18 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 310de0463beb..1faecef33009 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1113,6 +1113,7 @@ static void __loop_clr_fd(struct loop_device *lo)
struct queue_limits lim;
struct file *filp;
gfp_t gfp = lo->old_gfp_mask;
+ int err;
spin_lock_irq(&lo->lo_lock);
filp = lo->lo_backing_file;
@@ -1146,26 +1147,21 @@ static void __loop_clr_fd(struct loop_device *lo)
disk_force_media_change(lo->lo_disk);
- if (lo->lo_flags & LO_FLAGS_PARTSCAN) {
- int err;
-
- /*
- * 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
- * must be at least one and it can only become zero when the
- * current holder is released.
- */
- err = bdev_disk_changed(lo->lo_disk, false);
- if (err)
- pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
- __func__, lo->lo_number, err);
- /* Device is gone, no point in returning error */
- }
+ /*
+ * Remove all partitions, including partitions added manually with
+ * BLKPG, which may exist even if LO_FLAGS_PARTSCAN is not set.
+ *
+ * open_mutex has been held already in release path, so don't acquire
+ * it here.
+ */
+ err = bdev_disk_changed(lo->lo_disk, false);
+ if (err)
+ pr_warn("%s: partition scan of loop%d failed (rc=%d)\n",
+ __func__, lo->lo_number, err);
+ /* Device is gone, no point in returning error */
/*
- * lo->lo_state is set to Lo_unbound here after above partscan has
+ * lo->lo_state is set to Lo_unbound here after removing partitions has
* finished. There cannot be anybody else entering __loop_clr_fd() as
* Lo_rundown state protects us from all the other places trying to
* change the 'lo' device.