Messages in this thread Patch in this message |  | | | Date | Tue, 29 Oct 2002 17:20:16 +0000 | | Subject | [PATCH] dm update 3/3 | | From | Joe Thornber <> |
| |
Keep track of allocated minors in a bitset rather than abusing get_gendisk.
--- diff/drivers/md/dm.c 2002-10-29 16:22:36.000000000 +0000 +++ source/drivers/md/dm.c 2002-10-29 16:34:45.000000000 +0000 @@ -15,7 +15,7 @@ #include <linux/slab.h> static const char *_name = DM_NAME; -#define MAX_DEVICES 256 +#define MAX_DEVICES (1 << KDEV_MINOR_BITS) #define SECTOR_SHIFT 9 static int major = 0; @@ -483,13 +483,25 @@ return 0; } +/*----------------------------------------------------------------- + * A bitset is used to keep track of allocated minor numbers. + *---------------------------------------------------------------*/ +static spinlock_t _minor_lock = SPIN_LOCK_UNLOCKED; +static unsigned long _minor_bits[MAX_DEVICES / BITS_PER_LONG]; + +static void free_minor(int minor) +{ + spin_lock(&_minor_lock); + clear_bit(minor, _minor_bits); + spin_unlock(&_minor_lock); +} + /* * See if the device with a specific minor # is free. */ -static int specific_dev(int minor, struct mapped_device *md) +static int specific_minor(int minor) { - struct gendisk *disk; - int part; + int r = -EBUSY; if (minor >= MAX_DEVICES) { DMWARN("request for a mapped_device beyond MAX_DEVICES (%d)", @@ -497,26 +509,32 @@ return -EINVAL; } - disk = get_gendisk(MKDEV(_major, minor), &part); - if (disk) { - put_disk(disk); - return -EBUSY; + spin_lock(&_minor_lock); + if (!test_bit(minor, _minor_bits)) { + r = minor; + set_bit(minor, _minor_bits); } + spin_unlock(&_minor_lock); - return minor; + return r; } -static int any_old_dev(struct mapped_device *md) +static int any_old_minor(void) { - int i; + int i, r = -EBUSY; - for (i = 0; i < MAX_DEVICES; i++) - if (specific_dev(i, md) >= 0) { + spin_lock(&_minor_lock); + for (i = 0; i < MAX_DEVICES; i++) { + if (!test_bit(i, _minor_bits)) { + r = i; + set_bit(i, _minor_bits); DMWARN("allocating minor = %d", i); - return i; + break; } + } + spin_unlock(&_minor_lock); - return -EBUSY; + return r; } /* @@ -532,7 +550,7 @@ } /* get a minor number for the dev */ - minor = (minor < 0) ? any_old_dev(md) : specific_dev(minor, md); + minor = (minor < 0) ? any_old_minor() : specific_minor(minor); if (minor < 0) { kfree(md); return NULL; @@ -547,6 +565,7 @@ md->disk = alloc_disk(1); if (!md->disk) { + free_minor(md->disk->first_minor); kfree(md); return NULL; } @@ -566,6 +585,7 @@ static void free_dev(struct mapped_device *md) { + free_minor(md->disk->first_minor); del_gendisk(md->disk); put_disk(md->disk); kfree(md); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |