Skip to contentSkip to conversation

block: add GENHD_FL_UNPARTITIONABLE

PATCH In review Tejun Heo 3 participants 5 messages Aug 13, 2011 – Aug 15, 2011

Subsystems (2)
lore
Share & tools
lore

Tejun Heo

author
#0 lore raw

PATCH 1/1 block: add GENHD_FL_UNPARTITIONABLE

There are cases where suppressing partition scan is useful - e.g. for lo devices and pseudo SATA devices which advertise to be a disk but get upset on partition scan (some port multiplier control devices show such behavior).

This patch adds GENHD_FL_UNPARTITIONABLE which suppresses partition scan regardless of the number of possible partitions.

---
 include/linux/genhd.h |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
include/linux/genhd.h +3 -1
index 02fa469..a6f9329 100644
@@ -128,6 +128,7 @@ struct hd_struct {
 #define GENHD_FL_EXT_DEVT			64 /* allow extended devt */
 #define GENHD_FL_NATIVE_CAPACITY		128
 #define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE	256
+#define GENHD_FL_UNPARTITIONABLE		512
 
 enum {
 	DISK_EVENT_MEDIA_CHANGE			= 1 << 0, /* media changed */
@@ -236,7 +237,8 @@ static inline int disk_max_parts(struct gendisk *disk)
 
 static inline bool disk_partitionable(struct gendisk *disk)
 {
-	return disk_max_parts(disk) > 1;
+	return disk_max_parts(disk) > 1 &&
+		!(disk->flags & GENHD_FL_UNPARTITIONABLE);
 }
 
 static inline dev_t disk_devt(struct gendisk *disk)
#1 lore raw
Quoted 2 lines · Tejun Heo

There are cases where suppressing partition scan is useful - e.g. for lo devices

Err, partitioning loop devices is extremly useful.

author
#2 lore raw

Hello,

Quoted 5 lines · Christoph Hellwig
Quoted 2 lines · Tejun Heo

There are cases where suppressing partition scan is useful - e.g. for lo devices

Err, partitioning loop devices is extremly useful.

Oh yeah it is. It's to allow toggling it dynamically via losetup (currently, it's decided by module param). It's part of making lo more dynamic.

Thanks.

Signature · 1 line
tejun
#3 lore raw
In reply to Tejun Heo
Quoted 7 lines · On Sat, 13 August 2011 Tejun Heo <[email protected]> wrote:

There are cases where suppressing partition scan is useful - e.g. for lo devices and pseudo SATA devices which advertise to be a disk but get upset on partition scan (some port multiplier control devices show such behavior).

This patch adds GENHD_FL_UNPARTITIONABLE which suppresses partition scan regardless of the number of possible partitions.

Hm, would be nice if this could be set automatically for multipathed devices where active path is being controlled out-of-band (e.g. RDAC) and the inactive path rejects all IO.

Big question is how to let the kernel know early enough as userspace does not know about the device before kernel tries to probe partitions. Probably it would have to be triggered on the scsi-host side.

Bruno

author
#4 lore raw

PATCH 1/1 block: add GENHD_FL_NO_PART_SCAN

In reply to Tejun Heo

There are cases where suppressing partition scan is useful - e.g. for lo devices and pseudo SATA devices which advertise to be a disk but get upset on partition scan (some port multiplier control devices show such behavior).

This patch adds GENHD_FL_NO_PART_SCAN which suppresses partition scan regardless of the number of possible partitions. disk_partitionable() is renamed to disk_part_scan_enabled() as suppressing partition scan doesn't imply the device can't be partitioned using BLKPG_ADD/DEL_PARTITION calls from userland. show_partition() now directly tests disk_max_parts() to maintain backward-compatibility.

-v2: Updated to make it clear that only partition scan is suppressed
not partitioning itself as suggested by Kay Sievers.

---
 block/genhd.c         |    4 ++--
 block/ioctl.c         |    2 +-
 fs/block_dev.c        |    2 +-
 include/linux/genhd.h |    6 ++++--
 4 files changed, 8 insertions(+), 6 deletions(-)
block/genhd.c +2 -2
index 5cb51c5..2429ecb 100644
@@ -536,7 +536,7 @@ void register_disk(struct gendisk *disk)
 	disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj);
 
 	/* No minors to use for partitions */
-	if (!disk_partitionable(disk))
+	if (!disk_part_scan_enabled(disk))
 		goto exit;
 
 	/* No such device (e.g., media were just removed) */
@@ -841,7 +841,7 @@ static int show_partition(struct seq_file *seqf, void *v)
 	char buf[BDEVNAME_SIZE];
 
 	/* Don't show non-partitionable removeable devices or empty devices */
-	if (!get_capacity(sgp) || (!disk_partitionable(sgp) &&
+	if (!get_capacity(sgp) || (!disk_max_parts(sgp) &&
 				   (sgp->flags & GENHD_FL_REMOVABLE)))
 		return 0;
 	if (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)
block/ioctl.c +1 -1
index 1124cd2..5c74efc 100644
@@ -101,7 +101,7 @@ static int blkdev_reread_part(struct block_device *bdev)
 	struct gendisk *disk = bdev->bd_disk;
 	int res;
 
-	if (!disk_partitionable(disk) || bdev != bdev->bd_contains)
+	if (!disk_part_scan_enabled(disk) || bdev != bdev->bd_contains)
 		return -EINVAL;
 	if (!capable(CAP_SYS_ADMIN))
 		return -EACCES;
fs/block_dev.c +1 -1
index ff77262..0bed0d4 100644
@@ -971,7 +971,7 @@ static void flush_disk(struct block_device *bdev, bool kill_dirty)
 
 	if (!bdev->bd_disk)
 		return;
-	if (disk_partitionable(bdev->bd_disk))
+	if (disk_part_scan_enabled(bdev->bd_disk))
 		bdev->bd_invalidated = 1;
 }
 
include/linux/genhd.h +4 -2
index 02fa469..6d18f35 100644
@@ -128,6 +128,7 @@ struct hd_struct {
 #define GENHD_FL_EXT_DEVT			64 /* allow extended devt */
 #define GENHD_FL_NATIVE_CAPACITY		128
 #define GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE	256
+#define GENHD_FL_NO_PART_SCAN			512
 
 enum {
 	DISK_EVENT_MEDIA_CHANGE			= 1 << 0, /* media changed */
@@ -234,9 +235,10 @@ static inline int disk_max_parts(struct gendisk *disk)
 	return disk->minors;
 }
 
-static inline bool disk_partitionable(struct gendisk *disk)
+static inline bool disk_part_scan_enabled(struct gendisk *disk)
 {
-	return disk_max_parts(disk) > 1;
+	return disk_max_parts(disk) > 1 &&
+		!(disk->flags & GENHD_FL_NO_PART_SCAN);
 }
 
 static inline dev_t disk_devt(struct gendisk *disk)