de-printf the cache manager
[openafs.git] / src / afs / VNOPS / afs_vnop_open.c
index 000b999..6e8d2d5 100644 (file)
 
 
 #include <afsconfig.h>
-#include "../afs/param.h"
+#include "afs/param.h"
 
-RCSID("$Header$");
 
-#include "../afs/sysincludes.h"        /* Standard vendor system headers */
-#include "../afs/afsincludes.h"        /* Afs-based standard headers */
-#include "../afs/afs_stats.h" /* statistics */
-#include "../afs/afs_cbqueue.h"
-#include "../afs/nfsclient.h"
-#include "../afs/afs_osidnlc.h"
+#include "afs/sysincludes.h"   /* Standard vendor system headers */
+#include "afsincludes.h"       /* Afs-based standard headers */
+#include "afs/afs_stats.h"     /* statistics */
+#include "afs/afs_cbqueue.h"
+#include "afs/nfsclient.h"
+#include "afs/afs_osidnlc.h"
 
 
 
@@ -32,55 +31,79 @@ RCSID("$Header$");
  * checks are done here, instead they're done by afs_create or afs_access,
  * both called by the vn_open call.
  */
+int
 #ifdef AFS_SGI64_ENV
-afs_open(bhv, avcp, aflags, acred)
-    bhv_desc_t *bhv;
+afs_open(bhv_desc_t * bhv, struct vcache **avcp, afs_int32 aflags,
+        afs_ucred_t *acred)
 #else
-afs_open(avcp, aflags, acred)
+afs_open(struct vcache **avcp, afs_int32 aflags, afs_ucred_t *acred)
 #endif
-    register struct vcache **avcp;
-    afs_int32 aflags;
-    struct AFS_UCRED *acred; 
 {
     register afs_int32 code;
     struct vrequest treq;
-    register struct vcache *tvc;
+    struct vcache *tvc;
     int writing;
-    
+    struct afs_fakestat_state fakestate;
+
     AFS_STATCNT(afs_open);
-    if (code = afs_InitReq(&treq, acred)) return code;
+    if ((code = afs_InitReq(&treq, acred)))
+       return code;
 #ifdef AFS_SGI64_ENV
     /* avcpp can be, but is not necesarily, bhp's vnode. */
-    tvc = (struct vcache *)BHV_TO_VNODE(bhv);
+    tvc = VTOAFS(BHV_TO_VNODE(bhv));
 #else
     tvc = *avcp;
 #endif
     afs_Trace2(afs_iclSetp, CM_TRACE_OPEN, ICL_TYPE_POINTER, tvc,
               ICL_TYPE_INT32, aflags);
+    afs_InitFakeStat(&fakestate);
+
+    AFS_DISCON_LOCK();
+
+    code = afs_EvalFakeStat(&tvc, &fakestate, &treq);
+    if (code)
+       goto done;
     code = afs_VerifyVCache(tvc, &treq);
-    if (code) goto done;
-    if (aflags & (FWRITE | FTRUNC)) writing = 1;
-    else writing = 0;
+    if (code)
+       goto done;
+
+    ObtainReadLock(&tvc->lock);
+
+#ifdef AFS_DISCON_ENV
+    if (AFS_IS_DISCONNECTED && (afs_DCacheMissingChunks(tvc) != 0)) {
+       ReleaseReadLock(&tvc->lock);
+       /* printf("Network is down in afs_open: missing chunks\n"); */
+       code = ENETDOWN;
+       goto done;
+    }
+#endif
+
+    ReleaseReadLock(&tvc->lock);
+
+    if (aflags & (FWRITE | FTRUNC))
+       writing = 1;
+    else
+       writing = 0;
     if (vType(tvc) == VDIR) {
        /* directory */
        if (writing) {
            code = EISDIR;
            goto done;
-       }
-       else {
-           if (!afs_AccessOK(tvc, 
-                       ((tvc->states & CForeign) ? PRSFS_READ: PRSFS_LOOKUP),
-                       &treq, CHECK_MODE_BITS)) {
+       } else {
+           if (!afs_AccessOK
+               (tvc, ((tvc->f.states & CForeign) ? PRSFS_READ : PRSFS_LOOKUP),
+                &treq, CHECK_MODE_BITS)) {
                code = EACCES;
+               /* printf("afs_Open: no access for dir\n"); */
                goto done;
            }
        }
-    }
-    else {
+    } else {
 #ifdef AFS_SUN5_ENV
-       if (AFS_NFSXLATORREQ(acred) &&  (aflags & FREAD)) {
-           if (!afs_AccessOK(tvc, PRSFS_READ, &treq,
-                             CHECK_MODE_BITS|CMB_ALLOW_EXEC_AS_READ)) {
+       if (AFS_NFSXLATORREQ(acred) && (aflags & FREAD)) {
+           if (!afs_AccessOK
+               (tvc, PRSFS_READ, &treq,
+                CHECK_MODE_BITS | CMB_ALLOW_EXEC_AS_READ)) {
                code = EACCES;
                goto done;
            }
@@ -90,60 +113,94 @@ afs_open(avcp, aflags, acred)
        if (aflags & FRSHARE) {
            /*
             * Hack for AIX 4.1:
-            *  Apparently it is possible for a file to get mapped without
-            *  either VNOP_MAP or VNOP_RDWR being called, if (1) it is a
-            *  sharable library, and (2) it has already been loaded.  We must
-            *  ensure that the credp is up to date.  We detect the situation
-            *  by checking for O_RSHARE at open time.
+            *  Apparently it is possible for a file to get mapped without
+            *  either VNOP_MAP or VNOP_RDWR being called, if (1) it is a
+            *  sharable library, and (2) it has already been loaded.  We must
+            *  ensure that the credp is up to date.  We detect the situation
+            *  by checking for O_RSHARE at open time.
             */
            /*
             * We keep the caller's credentials since an async daemon will
             * handle the request at some point. We assume that the same
             * credentials will be used.
             */
-           ObtainWriteLock(&tvc->lock,140);
+           ObtainWriteLock(&tvc->lock, 140);
            if (!tvc->credp || (tvc->credp != acred)) {
-               crhold(acred);
-               if (tvc->credp) {
-                   struct ucred *crp = tvc->credp;
-                   tvc->credp = (struct ucred *)0;
-                   crfree(crp);
-               }
-               tvc->credp = acred;
+               crhold(acred);
+               if (tvc->credp) {
+                   struct ucred *crp = tvc->credp;
+                   tvc->credp = NULL;
+                   crfree(crp);
+               }
+               tvc->credp = acred;
            }
            ReleaseWriteLock(&tvc->lock);
        }
 #endif
        /* normal file or symlink */
-       osi_FlushText(tvc); /* only needed to flush text if text locked last time */
-#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
+       osi_FlushText(tvc);     /* only needed to flush text if text locked last time */
+#ifdef AFS_BOZONLOCK_ENV
        afs_BozonLock(&tvc->pvnLock, tvc);
 #endif
        osi_FlushPages(tvc, acred);
-#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_SUN5_ENV)
+#ifdef AFS_BOZONLOCK_ENV
        afs_BozonUnlock(&tvc->pvnLock, tvc);
 #endif
     }
     /* set date on file if open in O_TRUNC mode */
     if (aflags & FTRUNC) {
        /* this fixes touch */
-       ObtainWriteLock(&tvc->lock,123);
-       tvc->m.Date = osi_Time();
-       tvc->states |= CDirty;
+       ObtainWriteLock(&tvc->lock, 123);
+       tvc->f.m.Date = osi_Time();
+       tvc->f.states |= CDirty;
        ReleaseWriteLock(&tvc->lock);
     }
     ObtainReadLock(&tvc->lock);
-    if (writing) tvc->execsOrWriters++;
+    if (writing)
+       tvc->execsOrWriters++;
     tvc->opens++;
-#if defined(AFS_SGI_ENV)
+#if defined(AFS_SGI_ENV) || defined (AFS_LINUX26_ENV)
     if (writing && tvc->cred == NULL) {
        crhold(acred);
        tvc->cred = acred;
     }
 #endif
     ReleaseReadLock(&tvc->lock);
-done:
-    code = afs_CheckCode(code, &treq, 4); /* avoid AIX -O bug */
+    if ((afs_preCache != 0) && (writing == 0) && (vType(tvc) != VDIR) && 
+       (!afs_BBusy())) {
+       register struct dcache *tdc;
+       afs_size_t offset, len;
+
+       tdc = afs_GetDCache(tvc, 0, &treq, &offset, &len, 1);
+
+       ObtainSharedLock(&tdc->mflock, 865);
+       if (!(tdc->mflags & DFFetchReq)) {
+           struct brequest *bp;
+
+           /* start the daemon (may already be running, however) */
+           UpgradeSToWLock(&tdc->mflock, 666);
+           tdc->mflags |= DFFetchReq;  /* guaranteed to be cleared by BKG or 
+                                          GetDCache */
+           /* last parm (1) tells bkg daemon to do an afs_PutDCache when it 
+              is done, since we don't want to wait for it to finish before 
+              doing so ourselves.
+           */
+           bp = afs_BQueue(BOP_FETCH, tvc, B_DONTWAIT, 0, acred,
+                           (afs_size_t) 0, (afs_size_t) 1, tdc,
+                           (void *)0, (void *)0);
+           if (!bp) {
+               tdc->mflags &= ~DFFetchReq;
+           }
+           ReleaseWriteLock(&tdc->mflock);
+       } else {
+           ReleaseSharedLock(&tdc->mflock);
+       }
+    }  
+  done:
+    afs_PutFakeStat(&fakestate);
+    AFS_DISCON_UNLOCK();
+
+    code = afs_CheckCode(code, &treq, 4);      /* avoid AIX -O bug */
 
     afs_Trace2(afs_iclSetp, CM_TRACE_OPEN, ICL_TYPE_POINTER, tvc,
               ICL_TYPE_INT32, 999999);