From 0dc4722d7e86bf289f8e287a01532d90dda803a8 Mon Sep 17 00:00:00 2001 From: Michael Meffie Date: Sun, 18 May 2014 19:28:16 -0400 Subject: [PATCH] libafs: allocate vattrs in LINUX to reduce stack used Allocate temporary vattrs in LINUX to reduce the amount of stack space used. Reviewed-on: http://gerrit.openafs.org/11170 Tested-by: BuildBot Reviewed-by: Benjamin Kaduk Reviewed-by: Perry Ruiter Reviewed-by: Chas Williams - CONTRACTOR Reviewed-by: D Brashear (cherry picked from commit 40fb2650b783fbafe51aefd3d0af7a6b0536c265) Change-Id: I1f19c07a2ad0f8cdddd88e4528584caccaa403e0 Reviewed-on: http://gerrit.openafs.org/11339 Reviewed-by: Chas Williams - CONTRACTOR Tested-by: BuildBot Reviewed-by: Andrew Deason Reviewed-by: Benjamin Kaduk Reviewed-by: Stephan Wiesand --- src/afs/LINUX/osi_export.c | 16 ++++- src/afs/LINUX/osi_vfsops.c | 20 +++--- src/afs/LINUX/osi_vnodeops.c | 129 +++++++++++++++++++++++++---------- 3 files changed, 118 insertions(+), 47 deletions(-) diff --git a/src/afs/LINUX/osi_export.c b/src/afs/LINUX/osi_export.c index 931315689..1d564f7b7 100644 --- a/src/afs/LINUX/osi_export.c +++ b/src/afs/LINUX/osi_export.c @@ -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, 101); 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; } diff --git a/src/afs/LINUX/osi_vfsops.c b/src/afs/LINUX/osi_vfsops.c index c97a19b92..d6504ae5e 100644 --- a/src/afs/LINUX/osi_vfsops.c +++ b/src/afs/LINUX/osi_vfsops.c @@ -182,21 +182,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; } diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 1c36ed8f7..572496aac 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -985,7 +985,7 @@ check_bad_parent(struct dentry *dp) 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; @@ -995,6 +995,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->f.states & CStatd) { @@ -1003,6 +1008,7 @@ afs_linux_revalidate(struct dentry *dp) check_bad_parent(dp); /* check and correct mvid */ AFS_GUNLOCK(); + afs_DestroyAttr(vattr); return 0; } #endif @@ -1014,15 +1020,18 @@ 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); @@ -1100,20 +1109,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); @@ -1145,7 +1161,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; @@ -1223,6 +1238,7 @@ afs_linux_dentry_revalidate(struct dentry *dp, int flags) */ if (hgetlo(pvcp->f.m.DataVersion) > dp->d_time || !(vcp->f.states & CStatd)) { + struct vattr *vattr = NULL; int code; credp = crref(); @@ -1235,13 +1251,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 = hgetlo(pvcp->f.m.DataVersion); + + afs_DestroyAttr(vattr); } /* should we always update the attributes at this point? */ @@ -1396,25 +1421,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; @@ -1422,6 +1451,10 @@ afs_linux_create(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); @@ -1451,7 +1484,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) { @@ -1465,11 +1498,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; @@ -1612,7 +1654,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 @@ -1620,10 +1662,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); @@ -1639,20 +1688,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; @@ -1660,6 +1714,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); -- 2.39.5