From 1ac4eb1b84db2732b9c2645492daff9e25417475 Mon Sep 17 00:00:00 2001 From: Michael Meffie Date: Wed, 9 Apr 2014 08:40:21 -0400 Subject: [PATCH] libafs: reduce stack space in LINUX Allocate temporary vrequests to reduce the amount of stack space used. Change-Id: I71ed86b6345ce69a70f33cdbaf5eed2abb2cef19 Reviewed-on: http://gerrit.openafs.org/11005 Tested-by: BuildBot Reviewed-by: Chas Williams - CONTRACTOR Reviewed-by: D Brashear --- src/afs/LINUX/osi_export.c | 48 +++++++++++++++------------- src/afs/LINUX/osi_vfsops.c | 7 +++-- src/afs/LINUX/osi_vnodeops.c | 61 +++++++++++++++++++++--------------- 3 files changed, 67 insertions(+), 49 deletions(-) diff --git a/src/afs/LINUX/osi_export.c b/src/afs/LINUX/osi_export.c index 5d90cedf9..6771dad31 100644 --- a/src/afs/LINUX/osi_export.c +++ b/src/afs/LINUX/osi_export.c @@ -464,28 +464,29 @@ static int UnEvalFakeStat(struct vrequest *areq, struct vcache **vcpp) */ static struct dentry *get_dentry_from_fid(cred_t *credp, struct VenusFid *afid) { - struct vrequest treq; + struct vrequest *treq = NULL; struct vcache *vcp; struct vattr vattr; struct inode *ip; struct dentry *dp; afs_int32 code; - code = afs_InitReq(&treq, credp); + code = afs_CreateReq(&treq, credp); if (code) { #ifdef OSI_EXPORT_DEBUG - printk("afs: get_dentry_from_fid(0x%08x/%d/%d.%d): afs_InitReq: %d\n", + printk("afs: get_dentry_from_fid(0x%08x/%d/%d.%d): afs_CreateReq: %d\n", afid->Cell, afid->Fid.Volume, afid->Fid.Vnode, afid->Fid.Unique, code); #endif - return ERR_PTR(-afs_CheckCode(code, &treq, 101)); + return ERR_PTR(-afs_CheckCode(code, NULL, 101)); } - vcp = afs_GetVCache(afid, &treq, NULL, NULL); + vcp = afs_GetVCache(afid, treq, NULL, NULL); if (vcp == NULL) { #ifdef OSI_EXPORT_DEBUG printk("afs: get_dentry_from_fid(0x%08x/%d/%d.%d): no vcache\n", afid->Cell, afid->Fid.Volume, afid->Fid.Vnode, afid->Fid.Unique); #endif + afs_DestroyReq(treq); return NULL; } @@ -498,13 +499,13 @@ static struct dentry *get_dentry_from_fid(cred_t *credp, struct VenusFid *afid) * So, if this fails, we don't really care very much. */ if (vType(vcp) == VDIR && vcp->mvstat != 2 && !vcp->f.parent.vnode) - update_dir_parent(&treq, vcp); + update_dir_parent(treq, vcp); /* * If this is a volume root directory and fakestat is enabled, * we might need to replace the directory by a mount point. */ - code = UnEvalFakeStat(&treq, &vcp); + code = UnEvalFakeStat(treq, &vcp); if (code) { #ifdef OSI_EXPORT_DEBUG printk("afs: get_dentry_from_fid(0x%08x/%d/%d.%d): UnEvalFakeStat: %d\n", @@ -512,7 +513,9 @@ static struct dentry *get_dentry_from_fid(cred_t *credp, struct VenusFid *afid) code); #endif afs_PutVCache(vcp); - return ERR_PTR(-afs_CheckCode(code, &treq, 103)); + code = afs_CheckCode(code, treq, 103); + afs_DestroyReq(treq); + return ERR_PTR(-code); } ip = AFSTOV(vcp); @@ -530,10 +533,12 @@ static struct dentry *get_dentry_from_fid(cred_t *credp, struct VenusFid *afid) printk("afs: get_dentry_from_fid(0x%08x/%d/%d.%d): out of memory\n", afid->Cell, afid->Fid.Volume, afid->Fid.Vnode, afid->Fid.Unique); #endif + afs_DestroyReq(treq); return ERR_PTR(-ENOMEM); } dp->d_op = &afs_dentry_operations; + afs_DestroyReq(treq); return dp; } @@ -576,7 +581,7 @@ static int afs_export_get_name(struct dentry *parent, char *name, { struct afs_fakestat_state fakestate; struct get_name_data data; - struct vrequest treq; + struct vrequest *treq = NULL; struct volume *tvp; struct vcache *vcp; struct dcache *tdc; @@ -654,11 +659,10 @@ static int afs_export_get_name(struct dentry *parent, char *name, vcp->f.fid.Cell, vcp->f.fid.Fid.Volume, vcp->f.fid.Fid.Vnode, vcp->f.fid.Fid.Unique); #endif - - code = afs_InitReq(&treq, credp); + code = afs_CreateReq(&treq, credp); if (code) { #ifdef OSI_EXPORT_DEBUG - printk("afs: get_name(%s, 0x%08x/%d/%d.%d): afs_InitReq: %d\n", + printk("afs: get_name(%s, 0x%08x/%d/%d.%d): afs_CreateReq: %d\n", parent->d_name.name ? (char *)parent->d_name.name : "?", data.fid.Cell, data.fid.Fid.Volume, data.fid.Fid.Vnode, data.fid.Fid.Unique, code); @@ -675,7 +679,7 @@ static int afs_export_get_name(struct dentry *parent, char *name, data.fid.Cell, data.fid.Fid.Volume, data.fid.Fid.Vnode, data.fid.Fid.Unique); #endif - vcp = afs_GetVCache(&data.fid, &treq, NULL, NULL); + vcp = afs_GetVCache(&data.fid, treq, NULL, NULL); if (vcp) { ObtainReadLock(&vcp->lock); if (strlen(vcp->linkData + 1) <= NAME_MAX) @@ -696,7 +700,7 @@ static int afs_export_get_name(struct dentry *parent, char *name, goto done; } - code = afs_EvalFakeStat(&vcp, &fakestate, &treq); + code = afs_EvalFakeStat(&vcp, &fakestate, treq); if (code) goto done; @@ -718,7 +722,7 @@ static int afs_export_get_name(struct dentry *parent, char *name, redo: if (!(vcp->f.states & CStatd)) { - if ((code = afs_VerifyVCache2(vcp, &treq))) { + if ((code = afs_VerifyVCache2(vcp, treq))) { #ifdef OSI_EXPORT_DEBUG printk("afs: get_name(%s, 0x%08x/%d/%d.%d): VerifyVCache2(0x%08x/%d/%d.%d): %d\n", parent->d_name.name ? (char *)parent->d_name.name : "?", @@ -731,7 +735,7 @@ redo: } } - tdc = afs_GetDCache(vcp, (afs_size_t) 0, &treq, &dirOffset, &dirLen, 1); + tdc = afs_GetDCache(vcp, (afs_size_t) 0, treq, &dirOffset, &dirLen, 1); if (!tdc) { #ifdef OSI_EXPORT_DEBUG printk("afs: get_name(%s, 0x%08x/%d/%d.%d): GetDCache(0x%08x/%d/%d.%d): %d\n", @@ -813,9 +817,10 @@ done: data.fid.Fid.Vnode, data.fid.Fid.Unique, name); } afs_PutFakeStat(&fakestate); + code = afs_CheckCode(code, treq, 102); + afs_DestroyReq(treq); AFS_GUNLOCK(); crfree(credp); - code = afs_CheckCode(code, &treq, 102); return -code; } @@ -823,7 +828,7 @@ done: static struct dentry *afs_export_get_parent(struct dentry *child) { struct VenusFid tfid; - struct vrequest treq; + struct vrequest *treq = NULL; struct cell *tcell; struct vcache *vcp; struct dentry *dp = NULL; @@ -884,17 +889,17 @@ static struct dentry *afs_export_get_parent(struct dentry *child) } else { /* any other vnode */ if (vType(vcp) == VDIR && !vcp->f.parent.vnode && vcp->mvstat != 1) { - code = afs_InitReq(&treq, credp); + code = afs_CreateReq(&treq, credp); if (code) { #ifdef OSI_EXPORT_DEBUG - printk("afs: get_parent(0x%08x/%d/%d.%d): InitReq: %d\n", + printk("afs: get_parent(0x%08x/%d/%d.%d): afs_CreateReq: %d\n", vcp->f.fid.Cell, vcp->f.fid.Fid.Volume, vcp->f.fid.Fid.Vnode, vcp->f.fid.Fid.Unique, code); #endif dp = ERR_PTR(-ENOENT); goto done; } else { - code = update_dir_parent(&treq, vcp); + code = update_dir_parent(treq, vcp); if (code) { #ifdef OSI_EXPORT_DEBUG printk("afs: get_parent(0x%08x/%d/%d.%d): update_dir_parent: %d\n", @@ -931,6 +936,7 @@ static struct dentry *afs_export_get_parent(struct dentry *child) } done: + afs_DestroyReq(treq); AFS_GUNLOCK(); crfree(credp); diff --git a/src/afs/LINUX/osi_vfsops.c b/src/afs/LINUX/osi_vfsops.c index cad455567..9f0f2205c 100644 --- a/src/afs/LINUX/osi_vfsops.c +++ b/src/afs/LINUX/osi_vfsops.c @@ -171,13 +171,13 @@ static int afs_root(struct super_block *afsp) { afs_int32 code = 0; - struct vrequest treq; struct vcache *tvp = 0; AFS_STATCNT(afs_root); if (afs_globalVp && (afs_globalVp->f.states & CStatd)) { tvp = afs_globalVp; } else { + struct vrequest *treq = NULL; cred_t *credp = crref(); if (afs_globalVp) { @@ -185,8 +185,8 @@ afs_root(struct super_block *afsp) afs_globalVp = NULL; } - if (!(code = afs_InitReq(&treq, credp)) && !(code = afs_CheckInit())) { - tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL); + if (!(code = afs_CreateReq(&treq, credp)) && !(code = afs_CheckInit())) { + tvp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL); if (tvp) { struct inode *ip = AFSTOV(tvp); struct vattr vattr; @@ -208,6 +208,7 @@ afs_root(struct super_block *afsp) code = ENOENT; } crfree(credp); + afs_DestroyReq(treq); } afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, afs_globalVp, diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 91111e806..d6b04ac59 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -76,7 +76,7 @@ afs_convert_code(int code) { static inline int afs_linux_VerifyVCache(struct vcache *avc, cred_t **retcred) { cred_t *credp = NULL; - struct vrequest treq; + struct vrequest *treq = NULL; int code; if (avc->f.states & CStatd) { @@ -87,9 +87,11 @@ afs_linux_VerifyVCache(struct vcache *avc, cred_t **retcred) { credp = crref(); - code = afs_InitReq(&treq, credp); - if (code == 0) - code = afs_VerifyVCache2(avc, &treq); + code = afs_CreateReq(&treq, credp); + if (code == 0) { + code = afs_VerifyVCache2(avc, treq); + afs_DestroyReq(treq); + } if (retcred != NULL) *retcred = credp; @@ -278,7 +280,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) #endif { struct vcache *avc = VTOAFS(FILE_INODE(fp)); - struct vrequest treq; + struct vrequest *treq = NULL; struct dcache *tdc; int code; int offset; @@ -294,24 +296,24 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) AFS_GLOCK(); AFS_STATCNT(afs_readdir); - code = afs_convert_code(afs_InitReq(&treq, credp)); + code = afs_convert_code(afs_CreateReq(&treq, credp)); crfree(credp); if (code) goto out1; afs_InitFakeStat(&fakestat); - code = afs_convert_code(afs_EvalFakeStat(&avc, &fakestat, &treq)); + code = afs_convert_code(afs_EvalFakeStat(&avc, &fakestat, treq)); if (code) goto out; /* update the cache entry */ tagain: - code = afs_convert_code(afs_VerifyVCache2(avc, &treq)); + code = afs_convert_code(afs_VerifyVCache2(avc, treq)); if (code) goto out; /* get a reference to the entire directory */ - tdc = afs_GetDCache(avc, (afs_size_t) 0, &treq, &origOffset, &tlen, 1); + tdc = afs_GetDCache(avc, (afs_size_t) 0, treq, &origOffset, &tlen, 1); len = tlen; if (!tdc) { code = -ENOENT; @@ -459,6 +461,7 @@ unlock_out: out: afs_PutFakeStat(&fakestat); + afs_DestroyReq(treq); out1: AFS_GUNLOCK(); return code; @@ -714,7 +717,7 @@ afs_linux_flush(struct file *fp, fl_owner_t id) afs_linux_flush(struct file *fp) #endif { - struct vrequest treq; + struct vrequest *treq = NULL; struct vcache *vcp; cred_t *credp; int code; @@ -732,7 +735,7 @@ afs_linux_flush(struct file *fp) credp = crref(); vcp = VTOAFS(FILE_INODE(fp)); - code = afs_InitReq(&treq, credp); + code = afs_CreateReq(&treq, credp); if (code) goto out; /* If caching is bypassed for this file, or globally, just return 0 */ @@ -755,17 +758,18 @@ afs_linux_flush(struct file *fp) UpgradeSToWLock(&vcp->lock, 536); if (!AFS_IS_DISCONNECTED) { code = afs_StoreAllSegments(vcp, - &treq, + treq, AFS_SYNC | AFS_LASTSTORE); } else { afs_DisconAddDirty(vcp, VDisconWriteOsiFlush, 1); } ConvertWToSLock(&vcp->lock); } - code = afs_CheckCode(code, &treq, 54); + code = afs_CheckCode(code, treq, 54); ReleaseSharedLock(&vcp->lock); out: + afs_DestroyReq(treq); AFS_DISCON_UNLOCK(); AFS_GUNLOCK(); @@ -1190,17 +1194,21 @@ afs_linux_dentry_revalidate(struct dentry *dp, int flags) if (vcp->mvid && (vcp->f.states & CMValid)) { int tryEvalOnly = 0; int code = 0; - struct vrequest treq; + struct vrequest *treq = NULL; - code = afs_InitReq(&treq, credp); - if ( - (strcmp(dp->d_name.name, ".directory") == 0)) { + code = afs_CreateReq(&treq, credp); + if (code) { + dput(parent); + goto bad_dentry; + } + if ((strcmp(dp->d_name.name, ".directory") == 0)) { tryEvalOnly = 1; } if (tryEvalOnly) - code = afs_TryEvalFakeStat(&vcp, &fakestate, &treq); + code = afs_TryEvalFakeStat(&vcp, &fakestate, treq); else - code = afs_EvalFakeStat(&vcp, &fakestate, &treq); + code = afs_EvalFakeStat(&vcp, &fakestate, treq); + afs_DestroyReq(treq); if ((tryEvalOnly && vcp->mvstat == 1) || code) { /* a mount point, not yet replaced by its directory */ dput(parent); @@ -2129,21 +2137,22 @@ afs_linux_prefetch(struct file *fp, struct page *pp) if (AFS_CHUNKOFFSET(offset) == 0) { struct dcache *tdc; - struct vrequest treq; + struct vrequest *treq = NULL; cred_t *credp; credp = crref(); AFS_GLOCK(); - code = afs_InitReq(&treq, credp); + code = afs_CreateReq(&treq, credp); if (!code && !NBObtainWriteLock(&avc->lock, 534)) { tdc = afs_FindDCache(avc, offset); if (tdc) { if (!(tdc->mflags & DFNextStarted)) - afs_PrefetchChunk(avc, tdc, credp, &treq); + afs_PrefetchChunk(avc, tdc, credp, treq); afs_PutDCache(tdc); } ReleaseWriteLock(&avc->lock); } + afs_DestroyReq(treq); AFS_GUNLOCK(); crfree(credp); } @@ -2487,11 +2496,13 @@ afs_linux_prepare_writeback(struct vcache *avc) { static inline int afs_linux_dopartialwrite(struct vcache *avc, cred_t *credp) { - struct vrequest treq; + struct vrequest *treq = NULL; int code = 0; - if (!afs_InitReq(&treq, credp)) - code = afs_DoPartialWrite(avc, &treq); + if (!afs_CreateReq(&treq, credp)) { + code = afs_DoPartialWrite(avc, treq); + afs_DestroyReq(treq); + } return afs_convert_code(code); } -- 2.39.5