LINUX 5.3.0: Check for 'recurse' arg in keyring_search
[openafs.git] / src / afs / LINUX / osi_export.c
index 02d81be..926bd0d 100644 (file)
 #include <afsconfig.h>
 #include "afs/param.h"
 
-RCSID
-    ("$Header$");
 
 #include <linux/module.h> /* early to avoid printf->printk mapping */
 #include <linux/fs.h>
-#ifdef EXPORTFS_H_EXISTS
+#ifdef HAVE_LINUX_EXPORTFS_H
 #include <linux/exportfs.h>
 #endif
 #include "afs/sysincludes.h"
 #include "afsincludes.h"
 #include "afs/afs_dynroot.h"
-#include "h/smp_lock.h"
 
 #if !defined(AFS_NONFSTRANS)
 
@@ -352,7 +349,7 @@ redo:
      */
     while ((adp->f.states & CStatd)
           && (tdc->dflags & DFFetching)
-          && hsame(adp->f.m.DataVersion, tdc->f.versionNo)) {
+          && afs_IsDCacheFresh(tdc, adp)) {
        ReleaseReadLock(&tdc->lock);
        ReleaseSharedLock(&adp->lock);
        afs_osi_Sleep(&tdc->validPos);
@@ -360,7 +357,7 @@ redo:
        ObtainReadLock(&tdc->lock);
     }
     if (!(adp->f.states & CStatd)
-       || !hsame(adp->f.m.DataVersion, tdc->f.versionNo)) {
+       || !afs_IsDCacheFresh(tdc, adp)) {
        ReleaseReadLock(&tdc->lock);
        ReleaseSharedLock(&adp->lock);
        afs_PutDCache(tdc);
@@ -411,7 +408,7 @@ static int UnEvalFakeStat(struct vrequest *areq, struct vcache **vcpp)
     if (!afs_fakestat_enable)
        return 0;
 
-    if (*vcpp == afs_globalVp || vType(*vcpp) != VDIR || (*vcpp)->mvstat != 2)
+    if (*vcpp == afs_globalVp || vType(*vcpp) != VDIR || (*vcpp)->mvstat != AFS_MVSTAT_ROOT)
        return 0;
 
     /* Figure out what FID to look for */
@@ -467,28 +464,36 @@ 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 vattr *vattr = NULL;
     struct inode *ip;
     struct dentry *dp;
     afs_int32 code;
 
-    code = afs_InitReq(&treq, credp);
+    code = afs_CreateAttr(&vattr);
+    if (code) {
+       return ERR_PTR(-afs_CheckCode(code, NULL, 104));
+    }
+
+    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));
+       afs_DestroyAttr(vattr);
+       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);
+       afs_DestroyAttr(vattr);
        return NULL;
     }
 
@@ -500,14 +505,14 @@ static struct dentry *get_dentry_from_fid(cred_t *credp, struct VenusFid *afid)
      * at parentVnode on directories, except for VIOCGETVCXSTATUS.
      * 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);
+    if (vType(vcp) == VDIR && vcp->mvstat != AFS_MVSTAT_ROOT && !vcp->f.parent.vnode)
+       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",
@@ -515,12 +520,15 @@ 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, 101));
+       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();
@@ -533,10 +541,14 @@ 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);
+       afs_DestroyAttr(vattr);
        return ERR_PTR(-ENOMEM);
     }
 
     dp->d_op = &afs_dentry_operations;
+    afs_DestroyReq(treq);
+    afs_DestroyAttr(vattr);
     return dp;
 }
 
@@ -547,13 +559,11 @@ static struct dentry *afs_export_get_dentry(struct super_block *sb,
     cred_t *credp;
 
     credp = crref();
-    lock_kernel();
     AFS_GLOCK();
 
     dp = get_dentry_from_fid(credp, inump);
 
     AFS_GUNLOCK();
-    unlock_kernel();
     crfree(credp);
 
     return dp;
@@ -581,7 +591,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;
@@ -611,7 +621,6 @@ static int afs_export_get_name(struct dentry *parent, char *name,
     afs_InitFakeStat(&fakestate);
 
     credp = crref();
-    lock_kernel();
     AFS_GLOCK();
 
     vcp = VTOAFS(child->d_inode);
@@ -633,7 +642,7 @@ static int afs_export_get_name(struct dentry *parent, char *name,
     }
 
     /* Figure out what FID to look for */
-    if (vcp->mvstat == 2) { /* volume root */
+    if (vcp->mvstat == AFS_MVSTAT_ROOT) { /* volume root */
        tvp = afs_GetVolume(&vcp->f.fid, 0, READ_LOCK);
        if (!tvp) {
 #ifdef OSI_EXPORT_DEBUG
@@ -660,11 +669,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);
@@ -681,7 +689,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)
@@ -702,7 +710,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;
 
@@ -724,7 +732,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 : "?",
@@ -737,7 +745,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",
@@ -762,7 +770,7 @@ redo:
      */
     while ((vcp->f.states & CStatd)
           && (tdc->dflags & DFFetching)
-          && hsame(vcp->f.m.DataVersion, tdc->f.versionNo)) {
+          && afs_IsDCacheFresh(tdc, vcp)) {
        ReleaseReadLock(&tdc->lock);
        ReleaseReadLock(&vcp->lock);
        afs_osi_Sleep(&tdc->validPos);
@@ -770,7 +778,7 @@ redo:
        ObtainReadLock(&tdc->lock);
     }
     if (!(vcp->f.states & CStatd)
-       || !hsame(vcp->f.m.DataVersion, tdc->f.versionNo)) {
+       || !afs_IsDCacheFresh(tdc, vcp)) {
        ReleaseReadLock(&tdc->lock);
        ReleaseReadLock(&vcp->lock);
        afs_PutDCache(tdc);
@@ -819,10 +827,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();
-    unlock_kernel();
     crfree(credp);
-    code = afs_CheckCode(code, &treq, 102);
     return -code;
 }
 
@@ -830,7 +838,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;
@@ -848,7 +856,6 @@ static struct dentry *afs_export_get_parent(struct dentry *child)
     }
 
     credp = crref();
-    lock_kernel();
     AFS_GLOCK();
 
     vcp = VTOAFS(child->d_inode);
@@ -862,11 +869,11 @@ static struct dentry *afs_export_get_parent(struct dentry *child)
        /* a mount point in the dynmount directory */
        afs_GetDynrootMountFid(&tfid);
 
-    } else if (vcp->mvstat == 2) {
+    } else if (vcp->mvstat == AFS_MVSTAT_ROOT) {
        /* volume root */
        ObtainReadLock(&vcp->lock);
-       if (vcp->mvid && vcp->mvid->Fid.Volume) {
-           tfid = *vcp->mvid;
+       if (vcp->mvid.parent && vcp->mvid.parent->Fid.Volume) {
+           tfid = *vcp->mvid.parent;
            ReleaseReadLock(&vcp->lock);
        } else {
            ReleaseReadLock(&vcp->lock);
@@ -891,18 +898,18 @@ 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);
+       if (vType(vcp) == VDIR && !vcp->f.parent.vnode && vcp->mvstat != AFS_MVSTAT_MTPT) {
+           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",
@@ -939,8 +946,8 @@ static struct dentry *afs_export_get_parent(struct dentry *child)
     }
 
 done:
+    afs_DestroyReq(treq);
     AFS_GUNLOCK();
-    unlock_kernel();
     crfree(credp);
 
     return dp;