--- zzzz-none-000/linux-2.6.19.2/fs/block_dev.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/fs/block_dev.c 2008-04-10 16:00:22.000000000 +0000 @@ -642,47 +642,34 @@ } /** - * 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 struct bd_holder *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() * - * Add @bo to @bdev->bd_holder_list, create symlinks. + * If there is no matching entry with @bo in @bdev->bd_holder_list, + * add @bo to the list, create symlinks. * - * Returns 0 if symlinks are created. - * Returns -ve if something fails. + * Returns 0 if symlinks are created or already there. + * Returns -ve if something fails and @bo can be freed. */ static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) { + struct bd_holder *tmp; int ret; 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; @@ -753,7 +740,7 @@ struct kobject *kobj) { int res; - struct bd_holder *bo, *found; + struct bd_holder *bo; if (!kobj) return -EINVAL; @@ -764,16 +751,9 @@ mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION); res = bd_claim(bdev, holder); - if (res == 0) { - found = find_bd_holder(bdev, bo); - if (found == NULL) { - res = add_bd_holder(bdev, bo); - if (res) - bd_release(bdev); - } - } - - if (res || found) + if (res == 0) + res = add_bd_holder(bdev, bo); + if (res) free_bd_holder(bo); mutex_unlock(&bdev->bd_mutex); @@ -1087,8 +1067,10 @@ * For now, block device ->open() routine must _not_ * examine anything in 'inode' argument except ->i_rdev. */ - struct file fake_file = {}; - struct dentry fake_dentry = {}; + struct file fake_file; + struct dentry fake_dentry; + memset(&fake_file, 0, sizeof(struct file)); + memset(&fake_dentry, 0, sizeof(struct dentry)); fake_file.f_mode = mode; fake_file.f_flags = flags; fake_file.f_dentry = &fake_dentry; @@ -1108,8 +1090,10 @@ * For now, block device ->open() routine must _not_ * examine anything in 'inode' argument except ->i_rdev. */ - struct file fake_file = {}; - struct dentry fake_dentry = {}; + struct file fake_file; + struct dentry fake_dentry; + memset(&fake_file, 0, sizeof(struct file)); + memset(&fake_dentry, 0, sizeof(struct dentry)); fake_file.f_mode = mode; fake_file.f_flags = flags; fake_file.f_dentry = &fake_dentry; @@ -1127,8 +1111,10 @@ * For now, block device ->open() routine must _not_ * examine anything in 'inode' argument except ->i_rdev. */ - struct file fake_file = {}; - struct dentry fake_dentry = {}; + struct file fake_file; + struct dentry fake_dentry; + memset(&fake_file, 0, sizeof(struct file)); + memset(&fake_dentry, 0, sizeof(struct dentry)); fake_file.f_mode = mode; fake_file.f_flags = flags; fake_file.f_dentry = &fake_dentry; @@ -1151,8 +1137,6 @@ filp->f_flags |= O_LARGEFILE; bdev = bd_acquire(inode); - if (bdev == NULL) - return -ENOMEM; res = do_open(bdev, filp, BD_MUTEX_NORMAL); if (res)