LINUX: Sometimes let dentry_open handle refcounts
authorAndrew Deason <adeason@sinenomine.net>
Wed, 17 Apr 2013 23:04:58 +0000 (18:04 -0500)
committerDerrick Brashear <shadow@your-file-system.com>
Sat, 20 Apr 2013 15:24:23 +0000 (08:24 -0700)
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 <shadow@your-file-system.com>
Reviewed-by: Marc Dionne <marc.c.dionne@gmail.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Andrew Deason <adeason@sinenomine.net>

src/afs/LINUX/osi_compat.h
src/afs/LINUX/osi_file.c

index 6087d43..dc2c26a 100644 (file)
@@ -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
index eacffca..7389128 100644 (file)
@@ -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;
 }