static unsigned int major = 0;
static unsigned int _major = 0;
-static DEFINE_IDR(_minor_idr);
+static DEFINE_XARRAY_ALLOC(dm_minors);
static DEFINE_SPINLOCK(_minor_lock);
}
EXPORT_SYMBOL_GPL(dm_bio_get_target_bio_nr);
-#define MINOR_ALLOCED ((void *)-1)
-
/*
* Bits for the md->flags field.
*/
while (i--)
_exits[i]();
-
- /*
- * Should be empty by this point.
- */
- idr_destroy(&_minor_idr);
}
/*
return r;
}
-/*-----------------------------------------------------------------
- * An IDR is used to keep track of allocated minor numbers.
- *---------------------------------------------------------------*/
+/*
+ * An XArray is used to keep track of allocated minor numbers.
+ */
static void free_minor(int minor)
{
- spin_lock(&_minor_lock);
- idr_remove(&_minor_idr, minor);
- spin_unlock(&_minor_lock);
+ xa_erase(&dm_minors, minor);
}
/*
- * See if the device with a specific minor # is free.
+ * Allocate a specific minor # if free.
*/
-static int specific_minor(int minor)
+static int specific_minor(u32 minor)
{
- int r;
-
if (minor >= (1 << MINORBITS))
return -EINVAL;
- idr_preload(GFP_KERNEL);
- spin_lock(&_minor_lock);
-
- r = idr_alloc(&_minor_idr, MINOR_ALLOCED, minor, minor + 1, GFP_NOWAIT);
-
- spin_unlock(&_minor_lock);
- idr_preload_end();
- if (r < 0)
- return r == -ENOSPC ? -EBUSY : r;
- return 0;
+ return xa_insert(&dm_minors, minor, NULL, GFP_KERNEL);
}
-static int next_free_minor(int *minor)
+static int next_free_minor(u32 *minor)
{
- int r;
-
- idr_preload(GFP_KERNEL);
- spin_lock(&_minor_lock);
-
- r = idr_alloc(&_minor_idr, MINOR_ALLOCED, 0, 1 << MINORBITS, GFP_NOWAIT);
-
- spin_unlock(&_minor_lock);
- idr_preload_end();
- if (r < 0)
- return r;
- *minor = r;
- return 0;
+ return xa_alloc(&dm_minors, minor, NULL,
+ XA_LIMIT(0, (1 << MINORBITS) - 1), GFP_KERNEL);
}
static const struct block_device_operations dm_blk_dops;
dm_stats_init(&md->stats);
/* Populate the mapping, nobody knows we exist yet */
- spin_lock(&_minor_lock);
- old_md = idr_replace(&_minor_idr, md, minor);
- spin_unlock(&_minor_lock);
+ old_md = xa_store(&dm_minors, minor, md, 0);
- BUG_ON(old_md != MINOR_ALLOCED);
+ BUG_ON(old_md != NULL);
return md;
spin_lock(&_minor_lock);
- md = idr_find(&_minor_idr, minor);
- if (!md || md == MINOR_ALLOCED || (MINOR(disk_devt(dm_disk(md))) != minor) ||
+ md = xa_load(&dm_minors, minor);
+ if (!md || (MINOR(disk_devt(dm_disk(md))) != minor) ||
test_bit(DMF_FREEING, &md->flags) || dm_deleting_md(md)) {
md = NULL;
goto out;
might_sleep();
spin_lock(&_minor_lock);
- idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md))));
+ xa_store(&dm_minors, MINOR(disk_devt(dm_disk(md))), NULL, 0);
set_bit(DMF_FREEING, &md->flags);
spin_unlock(&_minor_lock);