diff options
-rw-r--r-- | block/genhd.c | 38 | ||||
-rw-r--r-- | drivers/ide/ide-disk.c | 6 | ||||
-rw-r--r-- | drivers/scsi/sd.c | 6 | ||||
-rw-r--r-- | lib/Kconfig.debug | 16 |
4 files changed, 63 insertions, 3 deletions
diff --git a/block/genhd.c b/block/genhd.c index ee4b13520e5..67e5a59ced2 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -299,6 +299,38 @@ EXPORT_SYMBOL(unregister_blkdev); | |||
299 | static struct kobj_map *bdev_map; | 299 | static struct kobj_map *bdev_map; |
300 | 300 | ||
301 | /** | 301 | /** |
302 | * blk_mangle_minor - scatter minor numbers apart | ||
303 | * @minor: minor number to mangle | ||
304 | * | ||
305 | * Scatter consecutively allocated @minor number apart if MANGLE_DEVT | ||
306 | * is enabled. Mangling twice gives the original value. | ||
307 | * | ||
308 | * RETURNS: | ||
309 | * Mangled value. | ||
310 | * | ||
311 | * CONTEXT: | ||
312 | * Don't care. | ||
313 | */ | ||
314 | static int blk_mangle_minor(int minor) | ||
315 | { | ||
316 | #ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT | ||
317 | int i; | ||
318 | |||
319 | for (i = 0; i < MINORBITS / 2; i++) { | ||
320 | int low = minor & (1 << i); | ||
321 | int high = minor & (1 << (MINORBITS - 1 - i)); | ||
322 | int distance = MINORBITS - 1 - 2 * i; | ||
323 | |||
324 | minor ^= low | high; /* clear both bits */ | ||
325 | low <<= distance; /* swap the positions */ | ||
326 | high >>= distance; | ||
327 | minor |= low | high; /* and set */ | ||
328 | } | ||
329 | #endif | ||
330 | return minor; | ||
331 | } | ||
332 | |||
333 | /** | ||
302 | * blk_alloc_devt - allocate a dev_t for a partition | 334 | * blk_alloc_devt - allocate a dev_t for a partition |
303 | * @part: partition to allocate dev_t for | 335 | * @part: partition to allocate dev_t for |
304 | * @gfp_mask: memory allocation flag | 336 | * @gfp_mask: memory allocation flag |
@@ -339,7 +371,7 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt) | |||
339 | return -EBUSY; | 371 | return -EBUSY; |
340 | } | 372 | } |
341 | 373 | ||
342 | *devt = MKDEV(BLOCK_EXT_MAJOR, idx); | 374 | *devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx)); |
343 | return 0; | 375 | return 0; |
344 | } | 376 | } |
345 | 377 | ||
@@ -361,7 +393,7 @@ void blk_free_devt(dev_t devt) | |||
361 | 393 | ||
362 | if (MAJOR(devt) == BLOCK_EXT_MAJOR) { | 394 | if (MAJOR(devt) == BLOCK_EXT_MAJOR) { |
363 | mutex_lock(&ext_devt_mutex); | 395 | mutex_lock(&ext_devt_mutex); |
364 | idr_remove(&ext_devt_idr, MINOR(devt)); | 396 | idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); |
365 | mutex_unlock(&ext_devt_mutex); | 397 | mutex_unlock(&ext_devt_mutex); |
366 | } | 398 | } |
367 | } | 399 | } |
@@ -473,7 +505,7 @@ struct gendisk *get_gendisk(dev_t devt, int *partno) | |||
473 | struct hd_struct *part; | 505 | struct hd_struct *part; |
474 | 506 | ||
475 | mutex_lock(&ext_devt_mutex); | 507 | mutex_lock(&ext_devt_mutex); |
476 | part = idr_find(&ext_devt_idr, MINOR(devt)); | 508 | part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt))); |
477 | if (part && get_disk(part_to_disk(part))) { | 509 | if (part && get_disk(part_to_disk(part))) { |
478 | *partno = part->partno; | 510 | *partno = part->partno; |
479 | disk = part_to_disk(part); | 511 | disk = part_to_disk(part); |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 7a88de9ada2..a072df5053a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -42,7 +42,13 @@ | |||
42 | #include <asm/div64.h> | 42 | #include <asm/div64.h> |
43 | 43 | ||
44 | #define IDE_DISK_PARTS (1 << PARTN_BITS) | 44 | #define IDE_DISK_PARTS (1 << PARTN_BITS) |
45 | |||
46 | #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) | ||
45 | #define IDE_DISK_MINORS IDE_DISK_PARTS | 47 | #define IDE_DISK_MINORS IDE_DISK_PARTS |
48 | #else | ||
49 | #define IDE_DISK_MINORS 1 | ||
50 | #endif | ||
51 | |||
46 | #define IDE_DISK_EXT_MINORS (IDE_DISK_PARTS - IDE_DISK_MINORS) | 52 | #define IDE_DISK_EXT_MINORS (IDE_DISK_PARTS - IDE_DISK_MINORS) |
47 | 53 | ||
48 | struct ide_disk_obj { | 54 | struct ide_disk_obj { |
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d1bb0e1d2d2..280d231a86e 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -87,7 +87,13 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); | |||
87 | MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); | 87 | MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); |
88 | 88 | ||
89 | #define SD_PARTS 64 | 89 | #define SD_PARTS 64 |
90 | |||
91 | #if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT) | ||
90 | #define SD_MINORS 16 | 92 | #define SD_MINORS 16 |
93 | #else | ||
94 | #define SD_MINORS 1 | ||
95 | #endif | ||
96 | |||
91 | #define SD_EXT_MINORS (SD_PARTS - SD_MINORS) | 97 | #define SD_EXT_MINORS (SD_PARTS - SD_MINORS) |
92 | 98 | ||
93 | static int sd_revalidate_disk(struct gendisk *); | 99 | static int sd_revalidate_disk(struct gendisk *); |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 0b504814e37..5a536f703a8 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -624,6 +624,22 @@ config BACKTRACE_SELF_TEST | |||
624 | 624 | ||
625 | Say N if you are unsure. | 625 | Say N if you are unsure. |
626 | 626 | ||
627 | config DEBUG_BLOCK_EXT_DEVT | ||
628 | bool "Force extended block device numbers and spread them" | ||
629 | depends on DEBUG_KERNEL | ||
630 | depends on BLOCK | ||
631 | default y | ||
632 | help | ||
633 | Conventionally, block device numbers are allocated from | ||
634 | predetermined contiguous area. However, extended block area | ||
635 | may introduce non-contiguous block device numbers. This | ||
636 | option forces most block device numbers to be allocated from | ||
637 | the extended space and spreads them to discover kernel or | ||
638 | userland code paths which assume predetermined contiguous | ||
639 | device number allocation. | ||
640 | |||
641 | Say N if you are unsure. | ||
642 | |||
627 | config LKDTM | 643 | config LKDTM |
628 | tristate "Linux Kernel Dump Test Tool Module" | 644 | tristate "Linux Kernel Dump Test Tool Module" |
629 | depends on DEBUG_KERNEL | 645 | depends on DEBUG_KERNEL |