summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJun'ichi Nomura <j-nomura@ce.jp.nec.com>2006-10-30 22:23:56 +0100
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-31 04:29:41 +0100
commitdf6c0cd9a872ebf2298f5d66d8c789f62dbe35fc (patch)
treec2d9ecf8ebb71f27aef1b5cc9dd94453e3d18150 /fs
parent[PATCH] fix bd_claim_by_kobject error handling (diff)
downloadlinux-df6c0cd9a872ebf2298f5d66d8c789f62dbe35fc.tar.xz
linux-df6c0cd9a872ebf2298f5d66d8c789f62dbe35fc.zip
[PATCH] clean up add_bd_holder()
add_bd_holder() is called from bd_claim_by_kobject to put a given struct bd_holder in the list if there is no matching entry. There are 3 possible results of add_bd_holder(): 1. there is no matching entry and add the given one to the list 2. there is matching entry, so just increment reference count of the existing one 3. something failed during its course 1 and 2 are successful cases. But for case 2, someone has to free the unused struct bd_holder. The current code frees it inside of add_bd_holder and returns same value 0 for both cases 1 and 2. However, it's natural and less error-prone if caller frees it since it's allocated by the caller. Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/block_dev.c53
1 files changed, 35 insertions, 18 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c
index b54b0a1b7c68..aaa8301f43f1 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -642,16 +642,38 @@ static void free_bd_holder(struct bd_holder *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);