[PATCH] dm: move idr_pre_get
authorJeff Mahoney <jeffm@suse.com>
Mon, 26 Jun 2006 07:27:21 +0000 (00:27 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 26 Jun 2006 16:58:34 +0000 (09:58 -0700)
idr_pre_get() can sleep while allocating memory.

The next patch will change _minor_lock into a spinlock, so this patch moves
idr_pre_get() outside the lock in preparation.

[akpm: too late for 2.6.17 - suitable for 2.6.17.x after it has settled]

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/md/dm.c

index 87d8ca1..6e577e7 100644 (file)
@@ -766,6 +766,10 @@ static int specific_minor(struct mapped_device *md, unsigned int minor)
        if (minor >= (1 << MINORBITS))
                return -EINVAL;
 
+       r = idr_pre_get(&_minor_idr, GFP_KERNEL);
+       if (!r)
+               return -ENOMEM;
+
        mutex_lock(&_minor_lock);
 
        if (idr_find(&_minor_idr, minor)) {
@@ -773,16 +777,9 @@ static int specific_minor(struct mapped_device *md, unsigned int minor)
                goto out;
        }
 
-       r = idr_pre_get(&_minor_idr, GFP_KERNEL);
-       if (!r) {
-               r = -ENOMEM;
-               goto out;
-       }
-
        r = idr_get_new_above(&_minor_idr, MINOR_ALLOCED, minor, &m);
-       if (r) {
+       if (r)
                goto out;
-       }
 
        if (m != minor) {
                idr_remove(&_minor_idr, m);
@@ -800,13 +797,11 @@ static int next_free_minor(struct mapped_device *md, unsigned int *minor)
        int r;
        unsigned int m;
 
-       mutex_lock(&_minor_lock);
-
        r = idr_pre_get(&_minor_idr, GFP_KERNEL);
-       if (!r) {
-               r = -ENOMEM;
-               goto out;
-       }
+       if (!r)
+               return -ENOMEM;
+
+       mutex_lock(&_minor_lock);
 
        r = idr_get_new(&_minor_idr, MINOR_ALLOCED, &m);
        if (r) {