From 716e7d3eb5042bb3f54b70280a17a072e577ec8d Mon Sep 17 00:00:00 2001 From: Erez Zadok Date: Thu, 3 Dec 2009 19:02:07 -0500 Subject: [PATCH] Unionfs: unlock lower parent inode correctly on error path 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 --- fs/unionfs/inode.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c index 07a2c17e896..0dc2e294f6f 100644 --- a/fs/unionfs/inode.c +++ b/fs/unionfs/inode.c @@ -125,12 +125,12 @@ 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 = init_lower_nd(&lower_nd, LOOKUP_CREATE); if (unlikely(err < 0)) - goto out; + goto out_unlock; err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, &lower_nd); release_lower_nd(&lower_nd, err); @@ -146,8 +146,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); @@ -390,7 +390,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; @@ -407,8 +407,8 @@ static int unionfs_symlink(struct inode *dir, struct dentry *dentry, } } +out_unlock: unlock_dir(lower_parent_dentry); - out: dput(wh_dentry); kfree(name); @@ -584,7 +584,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); @@ -599,8 +599,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); -- 2.34.1