windows-follow-backup-path-20071207
authorJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 7 Dec 2007 16:03:56 +0000 (16:03 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Fri, 7 Dec 2007 16:03:56 +0000 (16:03 +0000)
LICENSE MIT

Add a registry value, FollowBackupPath, that provides the Windows cache
manager with functionality equivalent to the UNIX afsd -backuptree option.

src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/cm_vnodeops.c
src/WINNT/afsd/cm_vnodeops.h

index 0e833da..7fe7f5b 100644 (file)
@@ -42,6 +42,7 @@ extern int RXSTATS_ExecuteRequest(struct rx_call *z_call);
 
 extern afs_int32 cryptall;
 extern int cm_enableServerLocks;
+extern int cm_followBackupPath;
 extern int cm_deleteReadOnly;
 #ifdef USE_BPLUS
 extern afs_int32 cm_BPlusTrees;
@@ -1137,7 +1138,15 @@ int afsd_InitCM(char **reasonP)
         cm_giveUpAllCBs = (unsigned short) dwValue;
     } 
     afsi_log("CM GiveUpAllCallBacks is %u", cm_giveUpAllCBs);
-    
+
+    dummyLen = sizeof(DWORD);
+    code = RegQueryValueEx(parmKey, "FollowBackupPath", NULL, NULL,
+                           (BYTE *) &dwValue, &dummyLen);
+    if (code == ERROR_SUCCESS) {
+        cm_followBackupPath = (unsigned short) dwValue;
+    } 
+    afsi_log("CM FollowBackupPath is %u", cm_followBackupPath);
+
     RegCloseKey (parmKey);
 
     cacheBlocks = ((afs_uint64)cacheSize * 1024) / blockSize;
index a491fa8..512bc03 100644 (file)
@@ -29,6 +29,8 @@ extern void afsi_log(char *pattern, ...);
 
 int cm_enableServerLocks = 1;
 
+int cm_followBackupPath = 0;
+
 /*
  * Case-folding array.  This was constructed by inspecting of SMBtrace output.
  * I do not know anything more about it.
@@ -1048,7 +1050,7 @@ long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp,
     char mtType;
     cm_fid_t tfid;
     size_t vnLength;
-    int type;
+    int targetType;
 
     if (scp->mountRootFid.cell != 0 && scp->mountRootGen >= cm_data.mountRootGen) {
         tfid = scp->mountRootFid;
@@ -1092,15 +1094,15 @@ long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp,
 
     vnLength = strlen(volNamep);
     if (vnLength >= 8 && strcmp(volNamep + vnLength - 7, ".backup") == 0)
-        type = BACKVOL;
+        targetType = BACKVOL;
     else if (vnLength >= 10
               && strcmp(volNamep + vnLength - 9, ".readonly") == 0)
-        type = ROVOL;
+        targetType = ROVOL;
     else
-        type = RWVOL;
+        targetType = RWVOL;
 
     /* check for backups within backups */
-    if (type == BACKVOL
+    if (targetType == BACKVOL
          && (scp->flags & (CM_SCACHEFLAG_RO | CM_SCACHEFLAG_PURERO))
          == CM_SCACHEFLAG_RO) {
         code = CM_ERROR_NOSUCHVOLUME;
@@ -1130,17 +1132,30 @@ long cm_FollowMountPoint(cm_scache_t *scp, cm_scache_t *dscp, cm_user_t *userp,
         lock_ReleaseMutex(&volp->mx);
 
         scp->mountRootFid.cell = cellp->cellID;
+        
+        /* if the mt pt originates in a .backup volume (not a .readonly)
+         * and FollowBackupPath is active, and if there is a .backup
+         * volume for the target, then use the .backup of the target
+         * instead of the read-write.
+         */
+        if (cm_followBackupPath && targetType == RWVOL &&
+            (scp->flags & CM_SCACHEFLAG_RO|CM_SCACHEFLAG_PURERO) == CM_SCACHEFLAG_RO &&
+            volp->bk.ID != 0) {
+            targetType = BACKVOL;
+        } 
         /* if the mt pt is in a read-only volume (not just a
          * backup), and if there is a read-only volume for the
-         * target, and if this is a type '#' mount point, use
+         * target, and if this is a targetType '#' mount point, use
          * the read-only, otherwise use the one specified.
          */
-        if (mtType == '#' && (scp->flags & CM_SCACHEFLAG_PURERO)
-             && volp->ro.ID != 0 && type == RWVOL)
-            type = ROVOL;
-        if (type == ROVOL)
+        else if (mtType == '#' && targetType == RWVOL && 
+                 (scp->flags & CM_SCACHEFLAG_PURERO) && 
+                 volp->ro.ID != 0) {
+            targetType = ROVOL;
+        }
+        if (targetType == ROVOL)
             scp->mountRootFid.volume = volp->ro.ID;
-        else if (type == BACKVOL)
+        else if (targetType == BACKVOL)
             scp->mountRootFid.volume = volp->bk.ID;
         else
             scp->mountRootFid.volume = volp->rw.ID;
index 96c41de..ac9d59f 100644 (file)
@@ -14,6 +14,8 @@ extern unsigned int cm_mountRootGen;
 
 extern int cm_enableServerLocks;
 
+extern int cm_followBackupPath;
+
 /* parms for attribute setting call */
 typedef struct cm_attr {
        int mask;