Unionfs: unlock lower parent inode correctly on error path
authorErez Zadok <ezk@cs.sunysb.edu>
Fri, 4 Dec 2009 00:16:36 +0000 (19:16 -0500)
committerErez Zadok <ezk@cs.sunysb.edu>
Fri, 4 Dec 2009 00:16:36 +0000 (19:16 -0500)
Bug fix: on some errors, lower directory inode may remain locked and hold a
reference.  This was in ->create, ->symlink, and ->mknod.

Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
fs/unionfs/inode.c

index eaac15527a6ae734e0872da81001962a85433c55..b6d3dbfc19167dad9743874ed446412839143752 100644 (file)
@@ -124,7 +124,7 @@ static int unionfs_create(struct inode *dir, struct dentry *dentry,
        lower_parent_dentry = lock_parent(lower_dentry);
        if (IS_ERR(lower_parent_dentry)) {
                err = PTR_ERR(lower_parent_dentry);
-               goto out;
+               goto out_unlock;
        }
 
        err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
@@ -141,8 +141,8 @@ static int unionfs_create(struct inode *dir, struct dentry *dentry,
                }
        }
 
+out_unlock:
        unlock_dir(lower_parent_dentry);
-
 out:
        if (!err) {
                unionfs_postcopyup_setmnt(dentry);
@@ -385,7 +385,7 @@ static int unionfs_symlink(struct inode *dir, struct dentry *dentry,
        lower_parent_dentry = lock_parent(lower_dentry);
        if (IS_ERR(lower_parent_dentry)) {
                err = PTR_ERR(lower_parent_dentry);
-               goto out;
+               goto out_unlock;
        }
 
        mode = S_IALLUGO;
@@ -402,8 +402,8 @@ static int unionfs_symlink(struct inode *dir, struct dentry *dentry,
                }
        }
 
+out_unlock:
        unlock_dir(lower_parent_dentry);
-
 out:
        dput(wh_dentry);
        kfree(name);
@@ -579,7 +579,7 @@ static int unionfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
        lower_parent_dentry = lock_parent(lower_dentry);
        if (IS_ERR(lower_parent_dentry)) {
                err = PTR_ERR(lower_parent_dentry);
-               goto out;
+               goto out_unlock;
        }
 
        err = vfs_mknod(lower_parent_dentry->d_inode, lower_dentry, mode, dev);
@@ -594,8 +594,8 @@ static int unionfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
                }
        }
 
+out_unlock:
        unlock_dir(lower_parent_dentry);
-
 out:
        dput(wh_dentry);
        kfree(name);