From d97c31bc045535c82a2e65a486376ba71f9ebaf7 Mon Sep 17 00:00:00 2001 From: Jun'ichi Nomura Date: Mon, 30 Oct 2006 16:23:56 -0500 Subject: [PATCH] --- yaml --- r: 40481 b: refs/heads/master c: df6c0cd9a872ebf2298f5d66d8c789f62dbe35fc h: refs/heads/master i: 40479: 1ffdaf85539a473203c77a2ce995e4b60f0e8daf v: v3 --- [refs] | 2 +- trunk/fs/block_dev.c | 53 +++++++++++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/[refs] b/[refs] index 69797142df18..06a9c7656adb 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bcb55165d3d1ae3ec95807d118fd6d5956cd127b +refs/heads/master: df6c0cd9a872ebf2298f5d66d8c789f62dbe35fc diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index b54b0a1b7c68..aaa8301f43f1 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -641,17 +641,39 @@ static void free_bd_holder(struct bd_holder *bo) kfree(bo); } +/** + * find_bd_holder - find matching struct bd_holder from the block device + * + * @bdev: struct block device to be searched + * @bo: target struct bd_holder + * + * Returns matching entry with @bo in @bdev->bd_holder_list. + * If found, increment the reference count and return the pointer. + * If not found, returns NULL. + */ +static int find_bd_holder(struct block_device *bdev, struct bd_holder *bo) +{ + struct bd_holder *tmp; + + list_for_each_entry(tmp, &bdev->bd_holder_list, list) + if (tmp->sdir == bo->sdir) { + tmp->count++; + return tmp; + } + + return NULL; +} + /** * add_bd_holder - create sysfs symlinks for bd_claim() relationship * * @bdev: block device to be bd_claimed * @bo: preallocated and initialized by alloc_bd_holder() * - * If there is no matching entry with @bo in @bdev->bd_holder_list, - * add @bo to the list, create symlinks. + * Add @bo to @bdev->bd_holder_list, create symlinks. * - * Returns 0 if symlinks are created or already there. - * Returns -ve if something fails and @bo can be freed. + * Returns 0 if symlinks are created. + * Returns -ve if something fails. */ static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) { @@ -661,15 +683,6 @@ static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) if (!bo) return -EINVAL; - list_for_each_entry(tmp, &bdev->bd_holder_list, list) { - if (tmp->sdir == bo->sdir) { - tmp->count++; - /* We've already done what we need to do here. */ - free_bd_holder(bo); - return 0; - } - } - if (!bd_holder_grab_dirs(bdev, bo)) return -EBUSY; @@ -740,7 +753,7 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder, struct kobject *kobj) { int res; - struct bd_holder *bo; + struct bd_holder *bo, *found; if (!kobj) return -EINVAL; @@ -752,11 +765,15 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder, mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); res = bd_claim(bdev, holder); if (res == 0) { - res = add_bd_holder(bdev, bo); - if (res) - bd_release(bdev); + found = find_bd_holder(bdev, bo); + if (found == NULL) { + res = add_bd_holder(bdev, bo); + if (res) + bd_release(bdev); + } } - if (res) + + if (res || found) free_bd_holder(bo); mutex_unlock(&bdev->bd_mutex);