libafs: reduce stack space in LINUX
authorMichael Meffie <mmeffie@sinenomine.net>
Wed, 9 Apr 2014 12:40:21 +0000 (08:40 -0400)
committerD Brashear <shadow@your-file-system.com>
Wed, 21 May 2014 20:12:50 +0000 (16:12 -0400)
Allocate temporary vrequests to reduce the amount
of stack space used.

Change-Id: I71ed86b6345ce69a70f33cdbaf5eed2abb2cef19
Reviewed-on: http://gerrit.openafs.org/11005
Tested-by: BuildBot <buildbot@rampaginggeek.com>
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 5d90ced..6771dad 100644 (file)
@@ -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);
 
index cad4555..9f0f220 100644 (file)
@@ -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,
index 91111e8..d6b04ac 100644 (file)
@@ -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);
 }