ukernel: make web enhancements the default
[openafs.git] / src / afs / VNOPS / afs_vnop_access.c
index a5cd799..4df769e 100644 (file)
@@ -22,8 +22,6 @@
 #include <afsconfig.h>
 #include "afs/param.h"
 
-RCSID
-    ("$Header$");
 
 #include "afs/sysincludes.h"   /* Standard vendor system headers */
 #include "afsincludes.h"       /* Afs-based standard headers */
@@ -53,12 +51,12 @@ static char fileModeMap[8] = {
 
 /* avc must be held.  Returns bit map of mode bits.  Ignores file mode bits */
 afs_int32
-afs_GetAccessBits(register struct vcache *avc, register afs_int32 arights,
-                 register struct vrequest *areq)
+afs_GetAccessBits(struct vcache *avc, afs_int32 arights,
+                 struct vrequest *areq)
 {
     AFS_STATCNT(afs_GetAccessBits);
     /* see if anyuser has the required access bits */
-    if ((arights & avc->anyAccess) == arights) {
+    if ((arights & avc->f.anyAccess) == arights) {
        return arights;
     }
 
@@ -72,30 +70,33 @@ afs_GetAccessBits(register struct vcache *avc, register afs_int32 arights,
        }
     }
 
-    if (!(avc->states & CForeign)) {
+    if (!(avc->f.states & CForeign)) {
        /* If there aren't any bits cached for this user (but the vnode
         * _is_ cached, obviously), make sure this user has valid tokens
         * before bothering with the RPC.  */
        struct unixuser *tu;
-       extern struct unixuser *afs_FindUser();
-       tu = afs_FindUser(areq->uid, avc->fid.Cell, READ_LOCK);
+       tu = afs_FindUser(areq->uid, avc->f.fid.Cell, READ_LOCK);
        if (!tu) {
-           return (arights & avc->anyAccess);
+           return (arights & avc->f.anyAccess);
        }
-       if ((tu->vid == UNDEFVID) || !(tu->states & UHasTokens)
-           || (tu->states & UTokensBad)) {
+       if (!(tu->states & UHasTokens) || (tu->states & UTokensBad)) {
            afs_PutUser(tu, READ_LOCK);
-           return (arights & avc->anyAccess);
+           return (arights & avc->f.anyAccess);
        } else {
            afs_PutUser(tu, READ_LOCK);
        }
     }
 
+    if (AFS_IS_DISCONNECTED && !AFS_IN_SYNC) {
+       /* If we get this far, we have to ask the network. But we can't, so
+        * they're out of luck... */
+       return 0;
+    } else
     {                          /* Ok, user has valid tokens, go ask the server. */
        struct AFSFetchStatus OutStatus;
        afs_int32 code;
 
-       code = afs_FetchStatus(avc, &avc->fid, areq, &OutStatus);
+       code = afs_FetchStatus(avc, &avc->f.fid, areq, &OutStatus);
        return (code ? 0 : OutStatus.CallerAccess & arights);
     }
 }
@@ -108,15 +109,15 @@ int
 afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq,
             afs_int32 check_mode_bits)
 {
-    register struct vcache *tvc;
+    struct vcache *tvc;
     struct VenusFid dirFid;
-    register afs_int32 mask;
+    afs_int32 mask;
     afs_int32 dirBits;
-    register afs_int32 fileBits;
+    afs_int32 fileBits;
 
     AFS_STATCNT(afs_AccessOK);
 
-    if ((vType(avc) == VDIR) || (avc->states & CForeign)) {
+    if ((vType(avc) == VDIR) || (avc->f.states & CForeign)) {
        /* rights are just those from acl */
        if (afs_InReadDir(avc)) {
            /* if we are already in readdir, then they may have read and
@@ -138,11 +139,11 @@ afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq,
         * rights for free. These rights will then be restricted by
         * the access mask. */
        dirBits = 0;
-       if (avc->parentVnode) {
-           dirFid.Cell = avc->fid.Cell;
-           dirFid.Fid.Volume = avc->fid.Fid.Volume;
-           dirFid.Fid.Vnode = avc->parentVnode;
-           dirFid.Fid.Unique = avc->parentUnique;
+       if (avc->f.parent.vnode) {
+           dirFid.Cell = avc->f.fid.Cell;
+           dirFid.Fid.Volume = avc->f.fid.Fid.Volume;
+           dirFid.Fid.Vnode = avc->f.parent.vnode;
+           dirFid.Fid.Unique = avc->f.parent.unique;
            /* Avoid this GetVCache call */
            tvc = afs_GetVCache(&dirFid, areq, NULL, NULL);
            if (tvc) {
@@ -174,10 +175,10 @@ afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq,
             * NFS translator and we don't know if it's a read or execute
             * on the NFS client, but both need to read the data.
             */
-           mask = (avc->m.Mode & 0700) >> 6;   /* file restrictions to use */
+           mask = (avc->f.m.Mode & 0700) >> 6; /* file restrictions to use */
            fileBits &= ~fileModeMap[mask];
            if (check_mode_bits & CMB_ALLOW_EXEC_AS_READ) {
-               if (avc->m.Mode & 0100)
+               if (avc->f.m.Mode & 0100)
                    fileBits |= PRSFS_READ;
            }
        }
@@ -188,15 +189,15 @@ afs_AccessOK(struct vcache *avc, afs_int32 arights, struct vrequest *areq,
 
 #if defined(AFS_SUN5_ENV) || (defined(AFS_SGI_ENV) && !defined(AFS_SGI65_ENV))
 int
-afs_access(OSI_VC_DECL(avc), register afs_int32 amode, int flags,
-          struct AFS_UCRED *acred)
+afs_access(OSI_VC_DECL(avc), afs_int32 amode, int flags,
+          afs_ucred_t *acred)
 #else
 int
-afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
-          struct AFS_UCRED *acred)
+afs_access(OSI_VC_DECL(avc), afs_int32 amode,
+          afs_ucred_t *acred)
 #endif
 {
-    register afs_int32 code;
+    afs_int32 code;
     struct vrequest treq;
     struct afs_fakestat_state fakestate;
     OSI_VC_CONVERT(avc);
@@ -204,15 +205,18 @@ afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
     AFS_STATCNT(afs_access);
     afs_Trace3(afs_iclSetp, CM_TRACE_ACCESS, ICL_TYPE_POINTER, avc,
               ICL_TYPE_INT32, amode, ICL_TYPE_OFFSET,
-              ICL_HANDLE_OFFSET(avc->m.Length));
+              ICL_HANDLE_OFFSET(avc->f.m.Length));
     afs_InitFakeStat(&fakestate);
     if ((code = afs_InitReq(&treq, acred)))
        return code;
 
+    AFS_DISCON_LOCK();
+
     if (afs_fakestat_enable && avc->mvstat == 1) {
        code = afs_TryEvalFakeStat(&avc, &fakestate, &treq);
         if (code == 0 && avc->mvstat == 1) {
            afs_PutFakeStat(&fakestate);
+           AFS_DISCON_UNLOCK();
            return 0;
         }
     } else {
@@ -221,23 +225,37 @@ afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
 
     if (code) {
        afs_PutFakeStat(&fakestate);
+       AFS_DISCON_UNLOCK();
        return code;
     }
 
-    code = afs_VerifyVCache(avc, &treq);
-    if (code) {
-       afs_PutFakeStat(&fakestate);
-       code = afs_CheckCode(code, &treq, 16);
-       return code;
+    if (vType(avc) != VDIR || !afs_InReadDir(avc)) {
+       code = afs_VerifyVCache(avc, &treq);
+       if (code) {
+           afs_PutFakeStat(&fakestate);
+           AFS_DISCON_UNLOCK();
+           code = afs_CheckCode(code, &treq, 16);
+           return code;
+       }
     }
 
     /* if we're looking for write access and we have a read-only file system, report it */
-    if ((amode & VWRITE) && (avc->states & CRO)) {
+    if ((amode & VWRITE) && (avc->f.states & CRO)) {
        afs_PutFakeStat(&fakestate);
+       AFS_DISCON_UNLOCK();
        return EROFS;
     }
+    
+    /* If we're looking for write access, and we're disconnected without logging, forget it */
+    if ((amode & VWRITE) && (AFS_IS_DISCONNECTED && !AFS_IS_DISCON_RW)) {
+        afs_PutFakeStat(&fakestate);
+       AFS_DISCON_UNLOCK();
+       /* printf("Network is down in afs_vnop_access\n"); */
+        return ENETDOWN;
+    }
+    
     code = 1;                  /* Default from here on in is access ok. */
-    if (avc->states & CForeign) {
+    if (avc->f.states & CForeign) {
        /* In the dfs xlator the EXEC bit is mapped to LOOKUP */
        if (amode & VEXEC)
            code = afs_AccessOK(avc, PRSFS_LOOKUP, &treq, CHECK_MODE_BITS);
@@ -276,21 +294,9 @@ afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
            if (amode & VEXEC) {
                code = afs_AccessOK(avc, PRSFS_READ, &treq, CHECK_MODE_BITS);
                if (code) {
-#ifdef AFS_OSF_ENV
-                   /*
-                    * The nfs server in read operations for non-owner of a file
-                    * will also check the access with the VEXEC (along with VREAD)
-                    * because for them exec is the same as read over the net because of
-                    * demand loading. But this means if the mode bit is '-rw' the call
-                    * will fail below; so for this particular case where both modes are
-                    * specified (only in rfs_read so far) and from the xlator requests
-                    * we return succes.
-                    */
-                   if (!((amode & VREAD) && AFS_NFSXLATORREQ(acred)))
-#endif
-                       if ((avc->m.Mode & 0100) == 0)
+                       if ((avc->f.m.Mode & 0100) == 0)
                            code = 0;
-               } else if (avc->m.Mode & 0100)
+               } else if (avc->f.m.Mode & 0100)
                    code = 1;
            }
            if (code && (amode & VWRITE)) {
@@ -304,7 +310,7 @@ afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
                 ** call returns failure. hence, we retry without any file 
                 ** mode bit checking */
                if (!code && AFS_NFSXLATORREQ(acred)
-                   && avc->m.Owner == ANONYMOUSID)
+                   && avc->f.m.Owner == ANONYMOUSID)
                    code =
                        afs_AccessOK(avc, PRSFS_WRITE, &treq,
                                     DONT_CHECK_MODE_BITS);
@@ -314,6 +320,9 @@ afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
        }
     }
     afs_PutFakeStat(&fakestate);
+
+    AFS_DISCON_UNLOCK();
+    
     if (code) {
        return 0;               /* if access is ok */
     } else {
@@ -322,20 +331,20 @@ afs_access(OSI_VC_DECL(avc), register afs_int32 amode,
     }
 }
 
-#if defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS)
+#if defined(UKERNEL)
 /*
  * afs_getRights
  * This function is just an interface to afs_GetAccessBits
  */
 int
-afs_getRights(OSI_VC_DECL(avc), register afs_int32 arights,
-             struct AFS_UCRED *acred)
+afs_getRights(OSI_VC_DECL(avc), afs_int32 arights,
+             afs_ucred_t *acred)
 {
-    register afs_int32 code;
+    afs_int32 code;
     struct vrequest treq;
     OSI_VC_CONVERT(avc);
 
-    if (code = afs_InitReq(&treq, acred))
+    if ((code = afs_InitReq(&treq, acred)))
        return code;
 
     code = afs_VerifyVCache(avc, &treq);
@@ -346,4 +355,4 @@ afs_getRights(OSI_VC_DECL(avc), register afs_int32 arights,
 
     return afs_GetAccessBits(avc, arights, &treq);
 }
-#endif /* defined(UKERNEL) && defined(AFS_WEB_ENHANCEMENTS) */
+#endif /* defined(UKERNEL) */