From: Erez Zadok Date: Sun, 4 Mar 2007 23:02:11 +0000 (-0500) Subject: fs/unionfs/: Fix unlocking in error paths X-Git-Tag: unionfs-2.1.1~194 X-Git-Url: https://git.fsl.cs.sunysb.edu/?a=commitdiff_plain;h=8061d5689bf08f0228aa50e7cf2a468092fd9a1b;p=unionfs-2.6.37.y.git fs/unionfs/: Fix unlocking in error paths Signed-off-by: Erez Zadok Signed-off-by: Josef 'Jeff' Sipek --- diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c index df929e9f0c4..967bb5b2c90 100644 --- a/fs/unionfs/lookup.c +++ b/fs/unionfs/lookup.c @@ -84,6 +84,7 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *n struct vfsmount *first_hidden_mnt = NULL; int locked_parent = 0; int locked_child = 0; + int allocated_new_info = 0; int opaque; char *whname = NULL; @@ -101,9 +102,11 @@ struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *n BUG_ON(UNIONFS_D(dentry) != NULL); locked_child = 1; } - if (lookupmode != INTERPOSE_PARTIAL) + if (lookupmode != INTERPOSE_PARTIAL) { if ((err = new_dentry_private_data(dentry))) goto out; + allocated_new_info = 1; + } /* must initialize dentry operations */ dentry->d_op = &unionfs_dops; @@ -380,7 +383,7 @@ out: if (locked_parent) unionfs_unlock_dentry(parent_dentry); dput(parent_dentry); - if (locked_child) + if (locked_child || (err && allocated_new_info)) unionfs_unlock_dentry(dentry); return ERR_PTR(err); } @@ -431,6 +434,7 @@ int new_dentry_private_data(struct dentry *dentry) int newsize; int oldsize = 0; struct unionfs_dentry_info *info = UNIONFS_D(dentry); + int unlock_on_err = 0; spin_lock(&dentry->d_lock); if (!info) { @@ -443,6 +447,7 @@ int new_dentry_private_data(struct dentry *dentry) mutex_init(&info->lock); mutex_lock(&info->lock); + unlock_on_err = 1; info->lower_paths = NULL; } else @@ -482,6 +487,8 @@ int new_dentry_private_data(struct dentry *dentry) out_free: kfree(info->lower_paths); + if (unlock_on_err) + mutex_unlock(&info->lock); out: free_dentry_private_data(info);