libafs: allow bkg daemon requests without creds
[openafs.git] / src / afs / afs_daemons.c
index 8938ea8..e50431f 100644 (file)
@@ -26,7 +26,7 @@
 
 #if defined(AFS_CACHE_BYPASS)
 #include "afs/afs_bypasscache.h"
-#endif// defined(AFS_CACHE_BYPASS)
+#endif /* AFS_CACHE_BYPASS */
 /* background request queue size */
 afs_lock_t afs_xbrs;           /* lock for brs */
 static int brsInit = 0;
@@ -90,7 +90,7 @@ afs_CheckServerDaemon(void)
     last10MinCheck = lastCheck = osi_Time();
     while (1) {
        if (afs_termState == AFSOP_STOP_CS) {
-           afs_termState = AFSOP_STOP_BKG;
+           afs_termState = AFSOP_STOP_TRUNCDAEMON;
            afs_osi_Wakeup(&afs_termState);
            break;
        }
@@ -108,7 +108,7 @@ afs_CheckServerDaemon(void)
        }
        /* shutdown check. */
        if (afs_termState == AFSOP_STOP_CS) {
-           afs_termState = AFSOP_STOP_BKG;
+           afs_termState = AFSOP_STOP_TRUNCDAEMON;
            afs_osi_Wakeup(&afs_termState);
            break;
        }
@@ -143,8 +143,6 @@ afs_Daemon(void)
     char cs_warned = 0;
 
     AFS_STATCNT(afs_Daemon);
-    last1MinCheck = last3MinCheck = last60MinCheck = last10MinCheck =
-    last5MinCheck = lastNMinCheck = 0;
 
     afs_rootFid.Fid.Volume = 0;
     while (afs_initState < 101)
@@ -182,25 +180,6 @@ afs_Daemon(void)
            afs_FlushActiveVcaches(0);  /* flush NFS writes */
        afs_FlushVCBs(1);       /* flush queued callbacks */
 
-#if defined(AFS_NBSD50_ENV)
-       /* XXXX */
-       {
-         int c1, c2;
-         c1 = ISAFS_GLOCK(); /* this thread owns the GLOCK */
-         if (!c1) {
-           c2 = mutex_tryenter(&afs_global_mtx); /* not held either */
-           if (c2)
-             AFS_GUNLOCK();
-         }
-         else
-           c2 = 0;
-         printf("afs_daemons periodic glock check: curthread owns glock %s; "
-                "glock held somewhere %s\n",
-                c1 ? "true" : "false",
-                c2 ? "true" : "false");
-       }
-#endif
-
        afs_MaybeWakeupTruncateDaemon();        /* free cache space if have too */
        rx_CheckPackets();      /* Does RX need more packets? */
 
@@ -235,15 +214,13 @@ afs_Daemon(void)
 
         if (afsd_dynamic_vcaches && (last5MinCheck + 300 < now)) {
             /* start with trying to drop us back to our base usage */
-            int anumber;
-            if (afs_maxvcount <= afs_cacheStats)
-                anumber = VCACHE_FREE;
-            else
-                anumber = VCACHE_FREE + (afs_maxvcount - afs_cacheStats);
-
-           ObtainWriteLock(&afs_xvcache, 734);
-            afs_ShakeLooseVCaches(anumber);
-           ReleaseWriteLock(&afs_xvcache);
+            int anumber = VCACHE_FREE + (afs_vcount - afs_cacheStats);
+
+           if (anumber > 0) {
+               ObtainWriteLock(&afs_xvcache, 734);
+               afs_ShakeLooseVCaches(anumber);
+               ReleaseWriteLock(&afs_xvcache);
+           }
             last5MinCheck = now;
         }
 
@@ -330,7 +307,7 @@ afs_Daemon(void)
            if (afs_CheckServerDaemonStarted)
                afs_termState = AFSOP_STOP_CS;
            else
-               afs_termState = AFSOP_STOP_BKG;
+               afs_termState = AFSOP_STOP_TRUNCDAEMON;
            afs_osi_Wakeup(&afs_termState);
            return;
        }
@@ -418,8 +395,13 @@ afs_CheckRootVolume(void)
                    spin_lock(&dp->d_lock);
 #endif
 #endif
+#if defined(D_ALIAS_IS_HLIST)
+                   hlist_del_init(&dp->d_alias);
+                   hlist_add_head(&dp->d_alias, &(AFSTOV(vcp)->i_dentry));
+#else
                    list_del_init(&dp->d_alias);
                    list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry));
+#endif
                    dp->d_inode = AFSTOV(vcp);
 #if defined(AFS_LINUX24_ENV)
 #if defined(AFS_LINUX26_ENV)
@@ -591,7 +573,6 @@ BStore(struct brequest *ab)
     AFS_STATCNT(BStore);
     if ((code = afs_InitReq(&treq, ab->cred)))
        return;
-    code = 0;
     tvc = ab->vc;
 #if defined(AFS_SGI_ENV)
     /*
@@ -618,7 +599,54 @@ BStore(struct brequest *ab)
 #endif
     /* now set final return code, and wakeup anyone waiting */
     if ((ab->flags & BUVALID) == 0) {
-       ab->code = afs_CheckCode(code, &treq, 43);      /* set final code, since treq doesn't go across processes */
+
+       /* To explain code_raw/code_checkcode:
+        * Anyone that's waiting won't have our treq, so they won't be able to
+        * call afs_CheckCode themselves on the return code we provide here.
+        * But if we give back only the afs_CheckCode value, they won't know
+        * what the "raw" value was. So give back both values, so the waiter
+        * can know the "raw" value for interpreting the value internally, as
+        * well as the afs_CheckCode value to give to the OS. */
+       ab->code_raw = code;
+       ab->code_checkcode = afs_CheckCode(code, &treq, 430);
+
+       ab->flags |= BUVALID;
+       if (ab->flags & BUWAIT) {
+           ab->flags &= ~BUWAIT;
+           afs_osi_Wakeup(ab);
+       }
+    }
+}
+
+static void
+BPartialStore(struct brequest *ab)
+{
+    struct vcache *tvc;
+    afs_int32 code;
+    struct vrequest treq;
+    int locked, shared_locked = 0;
+
+    AFS_STATCNT(BStore);
+    if ((code = afs_InitReq(&treq, ab->cred)))
+       return;
+    tvc = ab->vc;
+    locked = tvc->lock.excl_locked? 1:0;
+    if (!locked)
+        ObtainWriteLock(&tvc->lock, 1209);
+    else if (!(tvc->lock.excl_locked & WRITE_LOCK)) {
+       shared_locked = 1;
+       ConvertSToRLock(&tvc->lock);
+    }
+    code = afs_StoreAllSegments(tvc, &treq, AFS_ASYNC);
+    if (!locked)
+       ReleaseWriteLock(&tvc->lock);
+    else if (shared_locked)
+       ConvertSToRLock(&tvc->lock);
+    /* now set final return code, and wakeup anyone waiting */
+    if ((ab->flags & BUVALID) == 0) {
+       /* set final code, since treq doesn't go across processes */
+       ab->code_raw = code;
+       ab->code_checkcode = afs_CheckCode(code, &treq, 43);
        ab->flags |= BUVALID;
        if (ab->flags & BUWAIT) {
            ab->flags &= ~BUWAIT;
@@ -674,7 +702,9 @@ afs_BQueue(short aopcode, struct vcache *avc,
            tb->opcode = aopcode;
            tb->vc = avc;
            tb->cred = acred;
-           crhold(tb->cred);
+           if (tb->cred) {
+               crhold(tb->cred);
+           }
            if (avc) {
                AFS_FAST_HOLD(avc);
            }
@@ -685,7 +715,7 @@ afs_BQueue(short aopcode, struct vcache *avc,
            tb->ptr_parm[1] = apparm1;
            tb->ptr_parm[2] = apparm2;
            tb->flags = 0;
-           tb->code = 0;
+           tb->code_raw = tb->code_checkcode = 0;
            tb->ts = afs_brs_count++;
            /* if daemons are waiting for work, wake them up */
            if (afs_brsDaemons > 0) {
@@ -1015,7 +1045,7 @@ brequest_release(struct brequest *tb)
     afs_BRelease(tb);  /* this grabs and releases afs_xbrs lock */
 }
 
-#ifdef AFS_DARWIN80_ENV
+#ifdef AFS_NEW_BKG
 int
 afs_BackgroundDaemon(struct afs_uspc_param *uspc, void *param1, void *param2)
 #else
@@ -1032,7 +1062,7 @@ afs_BackgroundDaemon(void)
        /* Irix with "short stack" exits */
        afs_BackgroundDaemon_once();
 
-#ifdef AFS_DARWIN80_ENV
+#ifdef AFS_NEW_BKG
     /* If it's a re-entering syscall, complete the request and release */
     if (uspc->ts > -1) {
         tb = afs_brs;
@@ -1056,7 +1086,7 @@ afs_BackgroundDaemon(void)
 #endif
         /* Otherwise it's a new one */
        afs_nbrs++;
-#ifdef AFS_DARWIN80_ENV
+#ifdef AFS_NEW_BKG
     }
 #endif
 
@@ -1067,10 +1097,10 @@ afs_BackgroundDaemon(void)
 
        if (afs_termState == AFSOP_STOP_BKG) {
            if (--afs_nbrs <= 0)
-               afs_termState = AFSOP_STOP_TRUNCDAEMON;
+               afs_termState = AFSOP_STOP_RXCALLBACK;
            ReleaseWriteLock(&afs_xbrs);
            afs_osi_Wakeup(&afs_termState);
-#ifdef AFS_DARWIN80_ENV
+#ifdef AFS_NEW_BKG
            return -2;
 #else
            return;
@@ -1120,6 +1150,8 @@ afs_BackgroundDaemon(void)
                 return 0;
             }
 #endif
+           else if (tb->opcode == BOP_PARTIAL_STORE)
+               BPartialStore(tb);
            else
                panic("background bop");
            brequest_release(tb);
@@ -1134,7 +1166,7 @@ afs_BackgroundDaemon(void)
            afs_brsDaemons--;
        }
     }
-#ifdef AFS_DARWIN80_ENV
+#ifdef AFS_NEW_BKG
     return -2;
 #endif
 }
@@ -1198,7 +1230,7 @@ afs_sgidaemon(void)
            SPUNLOCK(afs_sgibklock, s);
            AFS_GLOCK();
            tdc->dflags &= ~DFEntryMod;
-           afs_WriteDCache(tdc, 1);
+           osi_Assert(afs_WriteDCache(tdc, 1) == 0);
            AFS_GUNLOCK();
            s = SPLOCK(afs_sgibklock);
        }