From: Andrew Deason Date: Wed, 17 Apr 2013 23:04:58 +0000 (-0500) Subject: LINUX: Sometimes let dentry_open handle refcounts X-Git-Tag: upstream/1.8.0_pre1^2~1211 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=e31240732cbe449fedea5095037ac08d1d513fa9;p=packages%2Fo%2Fopenafs.git LINUX: Sometimes let dentry_open handle refcounts When Linux changed dentry_open to use a 'path' argument, they also changed it so dentry_open handles incrementing the relevant ref counts. So now, sometimes we need to inc the dentry and vfsmount refcounts ourselves, and sometimes we need to leave them alone. To accommodate this, change afs_dentry_open to also handle refcounting itself, and 'get' the given dentry and vfsmount if necessary. Also note that currently, afs_linux_raw_open can call afs_dentry_open twice in the case of an error, but it does not dget(dp). This means that dp could be undercounted, since dentry_open on older kernels will dec the refcount on the given dentry in the case of an error. This change should also fix this so dp is not undercounted in that case. FIXES 131613 Change-Id: I0e9deb7ce57633ff65b76d2444a0416ecbe329fd Reviewed-on: http://gerrit.openafs.org/9801 Reviewed-by: Derrick Brashear Reviewed-by: Marc Dionne Tested-by: BuildBot Reviewed-by: Andrew Deason --- diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h index 6087d4377..dc2c26ac3 100644 --- a/src/afs/LINUX/osi_compat.h +++ b/src/afs/LINUX/osi_compat.h @@ -526,10 +526,11 @@ afs_dentry_open(struct dentry *dp, struct vfsmount *mnt, int flags, const struct struct file *filp; path.mnt = mnt; path.dentry = dp; + /* note that dentry_open will path_get for us */ filp = dentry_open(&path, flags, creds); return filp; #else - return dentry_open(dp, mnt, flags, creds); + return dentry_open(dget(dp), mntget(mnt), flags, creds); #endif } #endif diff --git a/src/afs/LINUX/osi_file.c b/src/afs/LINUX/osi_file.c index eacffca07..738912816 100644 --- a/src/afs/LINUX/osi_file.c +++ b/src/afs/LINUX/osi_file.c @@ -56,14 +56,17 @@ afs_linux_raw_open(afs_dcache_id_t *ainode) #if defined(STRUCT_TASK_STRUCT_HAS_CRED) /* Use stashed credentials - prevent selinux/apparmor problems */ - filp = afs_dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, cache_creds); + filp = afs_dentry_open(dp, afs_cacheMnt, O_RDWR, cache_creds); if (IS_ERR(filp)) - filp = afs_dentry_open(dp, mntget(afs_cacheMnt), O_RDWR, current_cred()); + filp = afs_dentry_open(dp, afs_cacheMnt, O_RDWR, current_cred()); #else - filp = dentry_open(dp, mntget(afs_cacheMnt), O_RDWR); + filp = dentry_open(dget(dp), mntget(afs_cacheMnt), O_RDWR); #endif if (IS_ERR(filp)) osi_Panic("Can't open file: %d\n", (int) PTR_ERR(filp)); + + dput(dp); + return filp; }