libafs: allocate vattrs in LINUX to reduce stack used
authorMichael Meffie <mmeffie@sinenomine.net>
Sun, 18 May 2014 23:28:16 +0000 (19:28 -0400)
committerD Brashear <shadow@your-file-system.com>
Sat, 31 May 2014 11:33:36 +0000 (07:33 -0400)
Allocate temporary vattrs in LINUX to reduce the amount
of stack space used.

Change-Id: Iafa8d920b7149486f1ea8fb1999c1f4c9a935615
Reviewed-on: http://gerrit.openafs.org/11170
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Benjamin Kaduk <kaduk@mit.edu>
Reviewed-by: Perry Ruiter <pruiter@sinenomine.net>
Reviewed-by: Chas Williams - CONTRACTOR <chas@cmf.nrl.navy.mil>
Reviewed-by: D Brashear <shadow@your-file-system.com>

src/afs/LINUX/osi_export.c
src/afs/LINUX/osi_vfsops.c
src/afs/LINUX/osi_vnodeops.c

index 6771dad..b68f6b2 100644 (file)
@@ -466,11 +466,16 @@ static struct dentry *get_dentry_from_fid(cred_t *credp, struct VenusFid *afid)
 {
     struct vrequest *treq = NULL;
     struct vcache *vcp;
-    struct vattr vattr;
+    struct vattr *vattr = NULL;
     struct inode *ip;
     struct dentry *dp;
     afs_int32 code;
 
+    code = afs_CreateAttr(&vattr);
+    if (code) {
+       return ERR_PTR(-afs_CheckCode(code, NULL, xxx));
+    }
+
     code = afs_CreateReq(&treq, credp);
     if (code) {
 #ifdef OSI_EXPORT_DEBUG
@@ -478,6 +483,7 @@ static struct dentry *get_dentry_from_fid(cred_t *credp, struct VenusFid *afid)
               afid->Cell, afid->Fid.Volume, afid->Fid.Vnode, afid->Fid.Unique,
               code);
 #endif
+       afs_DestroyAttr(vattr);
        return ERR_PTR(-afs_CheckCode(code, NULL, 101));
     }
     vcp = afs_GetVCache(afid, treq, NULL, NULL);
@@ -487,6 +493,7 @@ static struct dentry *get_dentry_from_fid(cred_t *credp, struct VenusFid *afid)
               afid->Cell, afid->Fid.Volume, afid->Fid.Vnode, afid->Fid.Unique);
 #endif
        afs_DestroyReq(treq);
+       afs_DestroyAttr(vattr);
        return NULL;
     }
 
@@ -515,12 +522,13 @@ static struct dentry *get_dentry_from_fid(cred_t *credp, struct VenusFid *afid)
        afs_PutVCache(vcp);
        code = afs_CheckCode(code, treq, 103);
        afs_DestroyReq(treq);
+       afs_DestroyAttr(vattr);
        return ERR_PTR(-code);
     }
 
     ip = AFSTOV(vcp);
-    afs_getattr(vcp, &vattr, credp);
-    afs_fill_inode(ip, &vattr);
+    afs_getattr(vcp, vattr, credp);
+    afs_fill_inode(ip, vattr);
 
     /* d_alloc_anon might block, so we shouldn't hold the glock */
     AFS_GUNLOCK();
@@ -534,11 +542,13 @@ static struct dentry *get_dentry_from_fid(cred_t *credp, struct VenusFid *afid)
               afid->Cell, afid->Fid.Volume, afid->Fid.Vnode, afid->Fid.Unique);
 #endif
        afs_DestroyReq(treq);
+       afs_DestroyAttr(vattr);
        return ERR_PTR(-ENOMEM);
     }
 
     dp->d_op = &afs_dentry_operations;
     afs_DestroyReq(treq);
+    afs_DestroyAttr(vattr);
     return dp;
 }
 
index 9f0f220..e6e0032 100644 (file)
@@ -189,21 +189,25 @@ afs_root(struct super_block *afsp)
            tvp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL);
            if (tvp) {
                struct inode *ip = AFSTOV(tvp);
-               struct vattr vattr;
+               struct vattr *vattr = NULL;
 
-               afs_getattr(tvp, &vattr, credp);
-               afs_fill_inode(ip, &vattr);
+               code = afs_CreateAttr(&vattr);
+               if (!code) {
+                   afs_getattr(tvp, vattr, credp);
+                   afs_fill_inode(ip, vattr);
 
-               /* setup super_block and mount point inode. */
-               afs_globalVp = tvp;
+                   /* setup super_block and mount point inode. */
+                   afs_globalVp = tvp;
 #if defined(HAVE_LINUX_D_MAKE_ROOT)
-               afsp->s_root = d_make_root(ip);
+                   afsp->s_root = d_make_root(ip);
 #else
-               afsp->s_root = d_alloc_root(ip);
+                   afsp->s_root = d_alloc_root(ip);
 #endif
 #if !defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP)
-               afsp->s_root->d_op = &afs_dentry_operations;
+                   afsp->s_root->d_op = &afs_dentry_operations;
 #endif
+                   afs_DestroyAttr(vattr);
+               }
            } else
                code = ENOENT;
        }
index d6b04ac..30e6f30 100644 (file)
@@ -953,7 +953,7 @@ fix_bad_parent(struct dentry *dp, cred_t *credp, struct vcache *vcp, struct vcac
 static int
 afs_linux_revalidate(struct dentry *dp)
 {
-    struct vattr vattr;
+    struct vattr *vattr = NULL;
     struct vcache *vcp = VTOAFS(dp->d_inode);
     cred_t *credp;
     int code;
@@ -963,6 +963,11 @@ afs_linux_revalidate(struct dentry *dp)
 
     AFS_GLOCK();
 
+    code = afs_CreateAttr(&vattr);
+    if (code) {
+       goto out;
+    }
+
 #ifdef notyet
     /* Make this a fast path (no crref), since it's called so often. */
     if (vcp->states & CStatd) {
@@ -977,6 +982,7 @@ afs_linux_revalidate(struct dentry *dp)
                crfree(credp);
            }
        }
+       afs_DestroyAttr(vattr);
        return 0;
     }
 #endif
@@ -988,16 +994,19 @@ afs_linux_revalidate(struct dentry *dp)
         (!afs_fakestat_enable || vcp->mvstat != 1) &&
        !afs_nfsexporter &&
        (vType(vcp) == VDIR || vType(vcp) == VLNK)) {
-       code = afs_CopyOutAttrs(vcp, &vattr);
+       code = afs_CopyOutAttrs(vcp, vattr);
     } else {
         credp = crref();
-       code = afs_getattr(vcp, &vattr, credp);
+       code = afs_getattr(vcp, vattr, credp);
        crfree(credp);
     }
 
     if (!code)
-        afs_fill_inode(AFSTOV(vcp), &vattr);
+        afs_fill_inode(AFSTOV(vcp), vattr);
 
+    afs_DestroyAttr(vattr);
+
+out:
     AFS_GUNLOCK();
 
     return afs_convert_code(code);
@@ -1075,20 +1084,27 @@ vattr2inode(struct inode *ip, struct vattr *vp)
 static int
 afs_notify_change(struct dentry *dp, struct iattr *iattrp)
 {
-    struct vattr vattr;
+    struct vattr *vattr = NULL;
     cred_t *credp = crref();
     struct inode *ip = dp->d_inode;
     int code;
 
-    VATTR_NULL(&vattr);
-    iattr2vattr(&vattr, iattrp);       /* Convert for AFS vnodeops call. */
-
     AFS_GLOCK();
-    code = afs_setattr(VTOAFS(ip), &vattr, credp);
+    code = afs_CreateAttr(&vattr);
+    if (code) {
+       goto out;
+    }
+
+    iattr2vattr(vattr, iattrp);        /* Convert for AFS vnodeops call. */
+
+    code = afs_setattr(VTOAFS(ip), vattr, credp);
     if (!code) {
-       afs_getattr(VTOAFS(ip), &vattr, credp);
-       vattr2inode(ip, &vattr);
+       afs_getattr(VTOAFS(ip), vattr, credp);
+       vattr2inode(ip, vattr);
     }
+    afs_DestroyAttr(vattr);
+
+out:
     AFS_GUNLOCK();
     crfree(credp);
     return afs_convert_code(code);
@@ -1152,7 +1168,6 @@ afs_linux_dentry_revalidate(struct dentry *dp, struct nameidata *nd)
 afs_linux_dentry_revalidate(struct dentry *dp, int flags)
 #endif
 {
-    struct vattr vattr;
     cred_t *credp = NULL;
     struct vcache *vcp, *pvcp, *tvc = NULL;
     struct dentry *parent;
@@ -1251,6 +1266,7 @@ afs_linux_dentry_revalidate(struct dentry *dp, int flags)
        }
 
        if (locked && (parent_dv > dp->d_time || !(vcp->f.states & CStatd))) {
+           struct vattr *vattr = NULL;
            int code;
 
            code = afs_lookup(pvcp, (char *)dp->d_name.name, &tvc, credp);
@@ -1262,13 +1278,22 @@ afs_linux_dentry_revalidate(struct dentry *dp, int flags)
                goto bad_dentry;
            }
 
-           if (afs_getattr(vcp, &vattr, credp)) {
+           code = afs_CreateAttr(&vattr);
+           if (code) {
+               dput(parent);
+               goto bad_dentry;
+           }
+
+           if (afs_getattr(vcp, vattr, credp)) {
                dput(parent);
+               afs_DestroyAttr(vattr);
                goto bad_dentry;
            }
 
-           vattr2inode(AFSTOV(vcp), &vattr);
+           vattr2inode(AFSTOV(vcp), vattr);
            dp->d_time = parent_dv;
+
+           afs_DestroyAttr(vattr);
        }
 
        /* should we always update the attributes at this point? */
@@ -1426,25 +1451,29 @@ afs_linux_create(struct inode *dip, struct dentry *dp, int mode,
 afs_linux_create(struct inode *dip, struct dentry *dp, int mode)
 #endif
 {
-    struct vattr vattr;
+    struct vattr *vattr = NULL;
     cred_t *credp = crref();
     const char *name = dp->d_name.name;
     struct vcache *vcp;
     int code;
 
-    VATTR_NULL(&vattr);
-    vattr.va_mode = mode;
-    vattr.va_type = mode & S_IFMT;
-
     AFS_GLOCK();
-    code = afs_create(VTOAFS(dip), (char *)name, &vattr, NONEXCL, mode,
+
+    code = afs_CreateAttr(&vattr);
+    if (code) {
+       goto out;
+    }
+    vattr->va_mode = mode;
+    vattr->va_type = mode & S_IFMT;
+
+    code = afs_create(VTOAFS(dip), (char *)name, vattr, NONEXCL, mode,
                      &vcp, credp);
 
     if (!code) {
        struct inode *ip = AFSTOV(vcp);
 
-       afs_getattr(vcp, &vattr, credp);
-       afs_fill_inode(ip, &vattr);
+       afs_getattr(vcp, vattr, credp);
+       afs_fill_inode(ip, vattr);
        insert_inode_hash(ip);
 #if !defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP)
        dp->d_op = &afs_dentry_operations;
@@ -1452,6 +1481,10 @@ afs_linux_create(struct inode *dip, struct dentry *dp, int mode)
        dp->d_time = parent_vcache_dv(dip, credp);
        d_instantiate(dp, ip);
     }
+
+    afs_DestroyAttr(vattr);
+
+out:
     AFS_GUNLOCK();
 
     crfree(credp);
@@ -1481,7 +1514,7 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
     code = afs_lookup(VTOAFS(dip), (char *)comp, &vcp, credp);
     
     if (vcp) {
-       struct vattr vattr;
+       struct vattr *vattr = NULL;
        struct vcache *parent_vc = VTOAFS(dip);
 
        if (parent_vc == vcp) {
@@ -1495,11 +1528,20 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
            goto done;
        }
 
+       code = afs_CreateAttr(&vattr);
+       if (code) {
+           afs_PutVCache(vcp);
+           AFS_GUNLOCK();
+           goto done;
+       }
+
        ip = AFSTOV(vcp);
-       afs_getattr(vcp, &vattr, credp);
-       afs_fill_inode(ip, &vattr);
+       afs_getattr(vcp, vattr, credp);
+       afs_fill_inode(ip, vattr);
        if (hlist_unhashed(&ip->i_hash))
            insert_inode_hash(ip);
+
+       afs_DestroyAttr(vattr);
     }
 #if !defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP)
     dp->d_op = &afs_dentry_operations;
@@ -1643,7 +1685,7 @@ afs_linux_symlink(struct inode *dip, struct dentry *dp, const char *target)
 {
     int code;
     cred_t *credp = crref();
-    struct vattr vattr;
+    struct vattr *vattr = NULL;
     const char *name = dp->d_name.name;
 
     /* If afs_symlink returned the vnode, we could instantiate the
@@ -1651,10 +1693,17 @@ afs_linux_symlink(struct inode *dip, struct dentry *dp, const char *target)
      */
     d_drop(dp);
 
-    VATTR_NULL(&vattr);
     AFS_GLOCK();
-    code = afs_symlink(VTOAFS(dip), (char *)name, &vattr, (char *)target, NULL,
-                      credp);
+    code = afs_CreateAttr(&vattr);
+    if (code) {
+       goto out;
+    }
+
+    code = afs_symlink(VTOAFS(dip), (char *)name, vattr, (char *)target, NULL,
+                       credp);
+    afs_DestroyAttr(vattr);
+
+out:
     AFS_GUNLOCK();
     crfree(credp);
     return afs_convert_code(code);
@@ -1670,20 +1719,25 @@ afs_linux_mkdir(struct inode *dip, struct dentry *dp, int mode)
     int code;
     cred_t *credp = crref();
     struct vcache *tvcp = NULL;
-    struct vattr vattr;
+    struct vattr *vattr = NULL;
     const char *name = dp->d_name.name;
 
-    VATTR_NULL(&vattr);
-    vattr.va_mask = ATTR_MODE;
-    vattr.va_mode = mode;
     AFS_GLOCK();
-    code = afs_mkdir(VTOAFS(dip), (char *)name, &vattr, &tvcp, credp);
+    code = afs_CreateAttr(&vattr);
+    if (code) {
+       goto out;
+    }
+
+    vattr->va_mask = ATTR_MODE;
+    vattr->va_mode = mode;
+
+    code = afs_mkdir(VTOAFS(dip), (char *)name, vattr, &tvcp, credp);
 
     if (tvcp) {
        struct inode *ip = AFSTOV(tvcp);
 
-       afs_getattr(tvcp, &vattr, credp);
-       afs_fill_inode(ip, &vattr);
+       afs_getattr(tvcp, vattr, credp);
+       afs_fill_inode(ip, vattr);
 
 #if !defined(STRUCT_SUPER_BLOCK_HAS_S_D_OP)
        dp->d_op = &afs_dentry_operations;
@@ -1691,6 +1745,9 @@ afs_linux_mkdir(struct inode *dip, struct dentry *dp, int mode)
        dp->d_time = hgetlo(VTOAFS(dip)->f.m.DataVersion);
        d_instantiate(dp, ip);
     }
+    afs_DestroyAttr(vattr);
+
+out:
     AFS_GUNLOCK();
 
     crfree(credp);