mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 11:11:45 -04:00
block: implement CONFIG_DEBUG_BLOCK_EXT_DEVT
Extended devt introduces non-contiguos device numbers. This patch implements a debug option which forces most devt allocations to be from the extended area and spreads them out. This is enabled by default if DEBUG_KERNEL is set and achieves... 1. Detects code paths in kernel or userland which expect predetermined consecutive device numbers. 2. When something goes wrong, avoid corruption as adding to the minor of earlier partition won't lead to the wrong but valid device. Signed-off-by: Tejun Heo <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
This commit is contained in:
parent
f615b48cc7
commit
870d665612
4 changed files with 63 additions and 3 deletions
|
|
@ -298,6 +298,38 @@ EXPORT_SYMBOL(unregister_blkdev);
|
|||
|
||||
static struct kobj_map *bdev_map;
|
||||
|
||||
/**
|
||||
* blk_mangle_minor - scatter minor numbers apart
|
||||
* @minor: minor number to mangle
|
||||
*
|
||||
* Scatter consecutively allocated @minor number apart if MANGLE_DEVT
|
||||
* is enabled. Mangling twice gives the original value.
|
||||
*
|
||||
* RETURNS:
|
||||
* Mangled value.
|
||||
*
|
||||
* CONTEXT:
|
||||
* Don't care.
|
||||
*/
|
||||
static int blk_mangle_minor(int minor)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_BLOCK_EXT_DEVT
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MINORBITS / 2; i++) {
|
||||
int low = minor & (1 << i);
|
||||
int high = minor & (1 << (MINORBITS - 1 - i));
|
||||
int distance = MINORBITS - 1 - 2 * i;
|
||||
|
||||
minor ^= low | high; /* clear both bits */
|
||||
low <<= distance; /* swap the positions */
|
||||
high >>= distance;
|
||||
minor |= low | high; /* and set */
|
||||
}
|
||||
#endif
|
||||
return minor;
|
||||
}
|
||||
|
||||
/**
|
||||
* blk_alloc_devt - allocate a dev_t for a partition
|
||||
* @part: partition to allocate dev_t for
|
||||
|
|
@ -339,7 +371,7 @@ int blk_alloc_devt(struct hd_struct *part, dev_t *devt)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
*devt = MKDEV(BLOCK_EXT_MAJOR, idx);
|
||||
*devt = MKDEV(BLOCK_EXT_MAJOR, blk_mangle_minor(idx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -361,7 +393,7 @@ void blk_free_devt(dev_t devt)
|
|||
|
||||
if (MAJOR(devt) == BLOCK_EXT_MAJOR) {
|
||||
mutex_lock(&ext_devt_mutex);
|
||||
idr_remove(&ext_devt_idr, MINOR(devt));
|
||||
idr_remove(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
|
||||
mutex_unlock(&ext_devt_mutex);
|
||||
}
|
||||
}
|
||||
|
|
@ -473,7 +505,7 @@ struct gendisk *get_gendisk(dev_t devt, int *partno)
|
|||
struct hd_struct *part;
|
||||
|
||||
mutex_lock(&ext_devt_mutex);
|
||||
part = idr_find(&ext_devt_idr, MINOR(devt));
|
||||
part = idr_find(&ext_devt_idr, blk_mangle_minor(MINOR(devt)));
|
||||
if (part && get_disk(part_to_disk(part))) {
|
||||
*partno = part->partno;
|
||||
disk = part_to_disk(part);
|
||||
|
|
|
|||
Loading…
Reference in a new issue