aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/genhd.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/block/genhd.c b/block/genhd.c
index ee4b13520e59..67e5a59ced2a 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -299,6 +299,38 @@ EXPORT_SYMBOL(unregister_blkdev);
299static struct kobj_map *bdev_map; 299static 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 */
314static 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);