]> www.infradead.org Git - users/willy/xarray.git/commitdiff
dm: Convert _minor_idr to XArray
authorMatthew Wilcox <willy@infradead.org>
Fri, 2 Nov 2018 03:26:21 +0000 (23:26 -0400)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 9 Aug 2019 01:38:13 +0000 (21:38 -0400)
Drop the use of the custom MINOR_ALLOCATED define in favour of using the
ability to allocate an index for a NULL pointer.  Rename the structure
to dm_minors.

It's probably possible to replace the _minor_lock with the xa_lock, but
it might be better to separate out the multiple things which are being
protected.

Signed-off-by: Matthew Wilcox <willy@infradead.org>
drivers/md/dm.c

index d0beef033e2f50148df8d3afdab450a0edb8c532..368723245e8a342affc6620b939af91e1cfad31b 100644 (file)
@@ -40,7 +40,7 @@ static const char *_name = DM_NAME;
 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);
 
@@ -127,8 +127,6 @@ unsigned dm_bio_get_target_bio_nr(const struct bio *bio)
 }
 EXPORT_SYMBOL_GPL(dm_bio_get_target_bio_nr);
 
-#define MINOR_ALLOCED ((void *)-1)
-
 /*
  * Bits for the md->flags field.
  */
@@ -311,11 +309,6 @@ static void __exit dm_exit(void)
 
        while (i--)
                _exits[i]();
-
-       /*
-        * Should be empty by this point.
-        */
-       idr_destroy(&_minor_idr);
 }
 
 /*
@@ -1821,53 +1814,29 @@ static int dm_any_congested(void *congested_data, int bdi_bits)
        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;
@@ -2009,11 +1978,9 @@ static struct mapped_device *alloc_dev(int minor)
        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;
 
@@ -2313,8 +2280,8 @@ struct mapped_device *dm_get_md(dev_t dev)
 
        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;
@@ -2370,7 +2337,7 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
        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);