linux-avoid-leaking-refs-20050211
authorChaskiel M Grundman <cg2v@andrew.cmu.edu>
Fri, 11 Feb 2005 22:37:31 +0000 (22:37 +0000)
committerDerrick Brashear <shadow@dementia.org>
Fri, 11 Feb 2005 22:37:31 +0000 (22:37 +0000)
FIXES 17451

hopefully this fixes all the not-able-to-unmount leaks

src/afs/LINUX/osi_misc.c
src/afs/LINUX/osi_vfsops.c
src/afs/afs_pioctl.c
src/afs/sysincludes.h

index 51755ad..61b1ec7 100644 (file)
@@ -28,44 +28,60 @@ RCSID
 #endif
 
 #if defined(AFS_LINUX24_ENV)
+/* LOOKUP_POSITIVE is becoming the default */
+#ifndef LOOKUP_POSITIVE
+#define LOOKUP_POSITIVE 0
+#endif
 /* Lookup name and return vnode for same. */
 int
-osi_lookupname(char *aname, uio_seg_t seg, int followlink,
-                       vnode_t ** dirvpp, struct dentry **dpp)
+osi_lookupname_internal(char *aname, int followlink, struct vfsmount **mnt,
+                       struct dentry **dpp)
 {
     int code;
-    extern struct nameidata afs_cacheNd;
-    struct nameidata *nd = &afs_cacheNd;
-
+    struct nameidata nd;
+    int flags = LOOKUP_POSITIVE;
     code = ENOENT;
-    if (seg == AFS_UIOUSER) {
-       code =
-           followlink ? user_path_walk(aname,
-                                       nd) : user_path_walk_link(aname, nd);
-    } else {
+
+    if (followlink)
+       flags |= LOOKUP_FOLLOW;
 #if defined(AFS_LINUX26_ENV)
-       code = path_lookup(aname, followlink ? LOOKUP_FOLLOW : 0, nd);
+    code = path_lookup(aname, flags, &nd);
 #else
-       if (path_init(aname, followlink ? LOOKUP_FOLLOW : 0, nd))
-           code = path_walk(aname, nd);
+    if (path_init(aname, flags, &nd))
+        code = path_walk(aname, &nd);
 #endif
-    }
 
     if (!code) {
-       if (nd->dentry->d_inode) {
-           *dpp = dget(nd->dentry);
-           code = 0;
-       } else {
-           code = ENOENT;
-           path_release(nd);
-       }
+       *dpp = dget(nd.dentry);
+        if (mnt)
+           *mnt = mntget(nd.mnt);
+       path_release(&nd);
     }
     return code;
 }
-#else
 int
 osi_lookupname(char *aname, uio_seg_t seg, int followlink, vnode_t ** dirvpp,
-              struct dentry **dpp)
+                       struct dentry **dpp)
+{
+    int code;
+    char *tname;
+    code = ENOENT;
+    if (seg == AFS_UIOUSER) {
+        tname = getname(aname);
+        if (IS_ERR(tname)) 
+            return PTR_ERR(tname);
+    } else {
+        tname = aname;
+    }
+    code = osi_lookupname_internal(tname, followlink, NULL, dpp);   
+    if (seg == AFS_UIOUSER) {
+        putname(tname);
+    }
+    return code;
+}
+#else
+int
+osi_lookupname(char *aname, uio_seg_t seg, int followlink, vnode_t ** dirvpp, struct dentry **dpp)
 {
     struct dentry *dp = NULL;
     int code;
@@ -94,12 +110,13 @@ int
 osi_InitCacheInfo(char *aname)
 {
     int code;
-    struct dentry *dp;
+    struct dentry *dp,*dpp;
     extern ino_t cacheInode;
     extern struct osi_dev cacheDev;
     extern afs_int32 afs_fsfragsize;
     extern struct super_block *afs_cacheSBp;
-    code = osi_lookupname(aname, AFS_UIOSYS, 1, NULL, &dp);
+    extern struct vfsmnt *afs_cacheMnt;
+    code = osi_lookupname_internal(aname, 1, &afs_cacheMnt, &dp);
     if (code)
        return ENOENT;
 
index b5df47d..2da99b0 100644 (file)
@@ -34,7 +34,7 @@ RCSID
 struct vcache *afs_globalVp = 0;
 struct vfs *afs_globalVFS = 0;
 #if defined(AFS_LINUX24_ENV)
-struct nameidata afs_cacheNd;
+struct vfsmount *afs_cacheMnt;
 #endif
 int afs_was_mounted = 0;       /* Used to force reload if mount/unmount/mount */
 
@@ -336,7 +336,7 @@ afs_put_super(struct super_block *sbp)
     afs_globalVp = 0;
     afs_shutdown();
 #if defined(AFS_LINUX24_ENV)
-    path_release(&afs_cacheNd);
+    mntput(afs_cacheMnt);
 #endif
 
     osi_linux_verify_alloced_memory();
index c1cd5e1..e7d3c14 100644 (file)
@@ -1154,6 +1154,7 @@ afs_HandlePioctl(struct vnode *avp, afs_int32 acom,
        } else {
            osi_FreeLargeSpace(inData);
        }
+       afs_PutFakeStat(&fakestate);
        return ENOMEM;
     }
     outSize = 0;
index 3423360..d592679 100644 (file)
@@ -84,6 +84,7 @@ struct xfs_inode_info {
 #include <asm/uaccess.h>
 #include <linux/list.h>
 #include <linux/dcache.h>
+#include <linux/mount.h>
 #include <linux/fs.h>
 #include <linux/quota.h>
 #include <linux/sched.h>