From ab939a6216161cd6afab74e60ca87d376145651c Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Fri, 7 Dec 2007 16:03:56 +0000 Subject: [PATCH] windows-follow-backup-path-20071207 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 | 11 ++++++++++- src/WINNT/afsd/cm_vnodeops.c | 37 +++++++++++++++++++++++++----------- src/WINNT/afsd/cm_vnodeops.h | 2 ++ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 0e833daf5..7fe7f5b77 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -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; diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index a491fa884..512bc0320 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -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; diff --git a/src/WINNT/afsd/cm_vnodeops.h b/src/WINNT/afsd/cm_vnodeops.h index 96c41dee0..ac9d59f3f 100644 --- a/src/WINNT/afsd/cm_vnodeops.h +++ b/src/WINNT/afsd/cm_vnodeops.h @@ -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; -- 2.39.5