afs: Return raw code from background daemons
[openafs.git] / src / afs / afs_daemons.c
index a4c9c88..da68e18 100644 (file)
@@ -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)
@@ -309,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;
        }
@@ -397,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)
@@ -570,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)
     /*
@@ -597,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, 43);
+
+       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;
@@ -664,7 +713,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) {
@@ -1046,7 +1095,7 @@ 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_NEW_BKG
@@ -1099,6 +1148,8 @@ afs_BackgroundDaemon(void)
                 return 0;
             }
 #endif
+           else if (tb->opcode == BOP_PARTIAL_STORE)
+               BPartialStore(tb);
            else
                panic("background bop");
            brequest_release(tb);