summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2022-05-27 07:58:06 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-06-14 18:41:52 +0200
commitd31b82b7f0cf0c5da22c1a9abdab50d5d042c27f (patch)
treeb16c3c3e37610d741c68fc8a4dc427282756efb7
parent7cbcf67ca409726ab7e2db8aa626a6e91d6ccdd3 (diff)
downloadlinux-d31b82b7f0cf0c5da22c1a9abdab50d5d042c27f.tar.gz
linux-d31b82b7f0cf0c5da22c1a9abdab50d5d042c27f.tar.bz2
linux-d31b82b7f0cf0c5da22c1a9abdab50d5d042c27f.zip
block, loop: support partitions without scanning
commit b9684a71fca793213378dd410cd11675d973eaa1 upstream. Historically we did distinguish between a flag that surpressed partition scanning, and a combinations of the minors variable and another flag if any partitions were supported. This was generally confusing and doesn't make much sense, but some corner case uses of the loop driver actually do want to support manually added partitions on a device that does not actively scan for partitions. To make things worsee the loop driver also wants to dynamically toggle the scanning for partitions on a live gendisk, which makes the disk->flags updates non-atomic. Introduce a new GD_SUPPRESS_PART_SCAN bit in disk->state that disables just scanning for partitions, and toggle that instead of GENHD_FL_NO_PART in the loop driver. Fixes: 1ebe2e5f9d68 ("block: remove GENHD_FL_EXT_DEVT") Reported-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Ming Lei <ming.lei@redhat.com> Link: https://lore.kernel.org/r/20220527055806.1972352-1-hch@lst.de Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--block/genhd.c2
-rw-r--r--drivers/block/loop.c8
-rw-r--r--include/linux/genhd.h1
3 files changed, 7 insertions, 4 deletions
diff --git a/block/genhd.c b/block/genhd.c
index 9d9d702d0778..c284c1cf3396 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -380,6 +380,8 @@ int disk_scan_partitions(struct gendisk *disk, fmode_t mode)
if (disk->flags & (GENHD_FL_NO_PART | GENHD_FL_HIDDEN))
return -EINVAL;
+ if (test_bit(GD_SUPPRESS_PART_SCAN, &disk->state))
+ return -EINVAL;
if (disk->open_partitions)
return -EBUSY;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index d46a3d5d0c2e..3411d3c0a5b0 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1067,7 +1067,7 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
lo->lo_flags |= LO_FLAGS_PARTSCAN;
partscan = lo->lo_flags & LO_FLAGS_PARTSCAN;
if (partscan)
- lo->lo_disk->flags &= ~GENHD_FL_NO_PART;
+ clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state);
loop_global_unlock(lo, is_loop);
if (partscan)
@@ -1186,7 +1186,7 @@ static void __loop_clr_fd(struct loop_device *lo, bool release)
*/
lo->lo_flags = 0;
if (!part_shift)
- lo->lo_disk->flags |= GENHD_FL_NO_PART;
+ set_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state);
mutex_lock(&lo->lo_mutex);
lo->lo_state = Lo_unbound;
mutex_unlock(&lo->lo_mutex);
@@ -1296,7 +1296,7 @@ out_unfreeze:
if (!err && (lo->lo_flags & LO_FLAGS_PARTSCAN) &&
!(prev_lo_flags & LO_FLAGS_PARTSCAN)) {
- lo->lo_disk->flags &= ~GENHD_FL_NO_PART;
+ clear_bit(GD_SUPPRESS_PART_SCAN, &lo->lo_disk->state);
partscan = true;
}
out_unlock:
@@ -2028,7 +2028,7 @@ static int loop_add(int i)
* userspace tools. Parameters like this in general should be avoided.
*/
if (!part_shift)
- disk->flags |= GENHD_FL_NO_PART;
+ set_bit(GD_SUPPRESS_PART_SCAN, &disk->state);
atomic_set(&lo->lo_refcnt, 0);
mutex_init(&lo->lo_mutex);
lo->lo_number = i;
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 6906a45bc761..2cb105f12028 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -110,6 +110,7 @@ struct gendisk {
#define GD_READ_ONLY 1
#define GD_DEAD 2
#define GD_NATIVE_CAPACITY 3
+#define GD_SUPPRESS_PART_SCAN 5
struct mutex open_mutex; /* open/close mutex */
unsigned open_partitions; /* number of open partitions */