From 50faf84b4b46b337cd576f4bcaceed423d63544b Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 27 Mar 2013 00:49:56 -0400 Subject: [PATCH] Windows: cache readonly volume size information Cache the volume size information for .readonly volumes which can be reset when the volume callback is broken. This reduces the number of RXAFS_GetVolumeStatus RPC calls issues on .readonly volumes. Change-Id: Ie0e63ca9082a004da71098e28df1315d42d364ff Reviewed-on: http://gerrit.openafs.org/9681 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_callback.c | 2 + src/WINNT/afsd/cm_volume.c | 17 ++++ src/WINNT/afsd/cm_volume.h | 2 + src/WINNT/afsrdr/user/RDRFunction.c | 126 +++++++++++++++++++--------- 4 files changed, 109 insertions(+), 38 deletions(-) diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 9e23278d8..a9deefa0d 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -227,6 +227,8 @@ cm_callbackDiscardROVolumeByFID(cm_fid_t *fidp) if (volp->cbExpiresRO) { volp->cbExpiresRO = 0; volp->cbIssuedRO = 0; + volp->volumeSizeRO = 0; + _InterlockedAnd(&volp->volumeSizeRO, ~CM_VOLUMEFLAG_RO_SIZE_VALID); if (volp->cbServerpRO) { cm_PutServer(volp->cbServerpRO); volp->cbServerpRO = NULL; diff --git a/src/WINNT/afsd/cm_volume.c b/src/WINNT/afsd/cm_volume.c index ddd3a5888..6337775f0 100644 --- a/src/WINNT/afsd/cm_volume.c +++ b/src/WINNT/afsd/cm_volume.c @@ -78,6 +78,9 @@ cm_ShutdownVolume(void) volp->cbExpiresRO = 0; volp->cbIssuedRO = 0; volp->cbServerpRO = NULL; + volp->volumeSizeRO = 0; + _InterlockedAnd(&volp->volumeSizeRO, ~CM_VOLUMEFLAG_RO_SIZE_VALID); + lock_FinalizeRWLock(&volp->rw); } @@ -119,6 +122,8 @@ void cm_InitVolume(int newFile, long maxVols) volp->cbExpiresRO = 0; volp->cbIssuedRO = 0; volp->cbServerpRO = NULL; + volp->volumeSizeRO = 0; + _InterlockedAnd(&volp->volumeSizeRO, ~CM_VOLUMEFLAG_RO_SIZE_VALID); } } osi_EndOnce(&once); @@ -1285,6 +1290,7 @@ cm_CheckOfflineVolumeState(cm_volume_t *volp, cm_vol_state_t *statep, afs_uint32 cm_req_t req; struct rx_connection * rxconnp; char volName[32]; + afs_uint32 volType; char offLineMsg[256]; char motd[256]; long alldown, alldeleted; @@ -1296,6 +1302,8 @@ cm_CheckOfflineVolumeState(cm_volume_t *volp, cm_vol_state_t *statep, afs_uint32 OfflineMsg = offLineMsg; MOTD = motd; + volType = cm_VolumeType(volp, volID); + if (statep->ID != 0 && (!volID || volID == statep->ID)) { /* create fid for volume root so that VNOVOL and VMOVED errors can be processed */ cm_SetFid(&vfid, volp->cellp->cellID, statep->ID, 1, 1); @@ -1354,6 +1362,15 @@ cm_CheckOfflineVolumeState(cm_volume_t *volp, cm_vol_state_t *statep, afs_uint32 rx_PutConnection(rxconnp); } while (cm_Analyze(connp, cm_rootUserp, &req, &vfid, NULL, 0, NULL, NULL, NULL, NULL, code)); code = cm_MapRPCError(code, &req); + + if (code == 0 && volType == ROVOL) + { + + lock_ObtainWrite(&volp->rw); + volp->volumeSizeRO = volStat.BlocksInUse * 1024; + _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID); + lock_ReleaseWrite(&volp->rw); + } } lock_ObtainWrite(&vscp->rw); diff --git a/src/WINNT/afsd/cm_volume.h b/src/WINNT/afsd/cm_volume.h index 8f3072eb1..8c430763a 100644 --- a/src/WINNT/afsd/cm_volume.h +++ b/src/WINNT/afsd/cm_volume.h @@ -53,6 +53,7 @@ typedef struct cm_volume { time_t cbIssuedRO; /* latest RO issue time; by cm_scacheLock */ time_t creationDateRO; /* latest volume creation date; 0 if unknown; by cm_scacheLock */ time_t lastUpdateTime; /* most recent volume location update cm_volumeLock */ + afs_uint64 volumeSizeRO; /* latest RO volume size */ } cm_volume_t; #define CM_VOLUMEFLAG_RESET 1 /* reload this info on next use */ @@ -60,6 +61,7 @@ typedef struct cm_volume { #define CM_VOLUMEFLAG_UPDATING_VL 8 #define CM_VOLUMEFLAG_DFS_VOLUME 16 #define CM_VOLUMEFLAG_NOEXIST 32 +#define CM_VOLUMEFLAG_RO_SIZE_VALID 64 #define CM_VOLUME_QFLAG_IN_HASH 1 #define CM_VOLUME_QFLAG_IN_LRU_QUEUE 2 diff --git a/src/WINNT/afsrdr/user/RDRFunction.c b/src/WINNT/afsrdr/user/RDRFunction.c index 4207e1028..fca4332f9 100644 --- a/src/WINNT/afsrdr/user/RDRFunction.c +++ b/src/WINNT/afsrdr/user/RDRFunction.c @@ -5894,31 +5894,56 @@ RDR_GetVolumeInfo( IN cm_user_t *userp, if (cm_volumeInfoReadOnlyFlag && (volType == ROVOL || volType == BACKVOL)) pResultCB->FileSystemAttributes |= FILE_READ_ONLY_VOLUME; - flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS; - if (scp->volumeCreationDate == 0) - flags |= CM_SCACHESYNC_FORCECB; - code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ, flags); - if (code == 0) + code = -1; + + if ( volType == ROVOL && + (volp->flags & CM_VOLUMEFLAG_RO_SIZE_VALID)) + { + lock_ObtainRead(&volp->rw); + if (volp->flags & CM_VOLUMEFLAG_RO_SIZE_VALID) { + volStat.BlocksInUse = volp->volumeSizeRO / 1024; + code = 0; + } + lock_ReleaseRead(&volp->rw); + } + + if (code == -1) { - sync_done = 1; + flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS; + if (scp->volumeCreationDate == 0) + flags |= CM_SCACHESYNC_FORCECB; + code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ, flags); + if (code == 0) + { + sync_done = 1; - Name = volName; - OfflineMsg = offLineMsg; - MOTD = motd; - lock_ReleaseWrite(&scp->rw); - scp_locked = 0; + Name = volName; + OfflineMsg = offLineMsg; + MOTD = motd; + lock_ReleaseWrite(&scp->rw); + scp_locked = 0; + + do { + code = cm_ConnFromFID(&scp->fid, userp, &req, &connp); + if (code) continue; - do { - code = cm_ConnFromFID(&scp->fid, userp, &req, &connp); - if (code) continue; + rxconnp = cm_GetRxConn(connp); + code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume, + &volStat, &Name, &OfflineMsg, &MOTD); + rx_PutConnection(rxconnp); - rxconnp = cm_GetRxConn(connp); - code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume, - &volStat, &Name, &OfflineMsg, &MOTD); - rx_PutConnection(rxconnp); + } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code)); + code = cm_MapRPCError(code, &req); + + if (code == 0 && volType == ROVOL) + { - } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code)); - code = cm_MapRPCError(code, &req); + lock_ObtainWrite(&volp->rw); + volp->volumeSizeRO = volStat.BlocksInUse * 1024; + _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID); + lock_ReleaseWrite(&volp->rw); + } + } } if ( scp->volumeCreationDate ) @@ -6098,29 +6123,54 @@ RDR_GetVolumeSizeInfo( IN cm_user_t *userp, volType = cm_VolumeType(volp, scp->fid.volume); - code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ, - CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); - if (code == 0) + code = -1; + + if ( volType == ROVOL && + (volp->flags & CM_VOLUMEFLAG_RO_SIZE_VALID)) + { + lock_ObtainRead(&volp->rw); + if (volp->flags & CM_VOLUMEFLAG_RO_SIZE_VALID) { + volStat.BlocksInUse = volp->volumeSizeRO / 1024; + code = 0; + } + lock_ReleaseRead(&volp->rw); + } + + if (code == -1) { - sync_done = 1; + code = cm_SyncOp(scp, NULL, userp, &req, PRSFS_READ, + CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS); + if (code == 0) + { + sync_done = 1; - Name = volName; - OfflineMsg = offLineMsg; - MOTD = motd; - lock_ReleaseWrite(&scp->rw); - scp_locked = 0; + Name = volName; + OfflineMsg = offLineMsg; + MOTD = motd; + lock_ReleaseWrite(&scp->rw); + scp_locked = 0; - do { - code = cm_ConnFromFID(&scp->fid, userp, &req, &connp); - if (code) continue; + do { + code = cm_ConnFromFID(&scp->fid, userp, &req, &connp); + if (code) continue; - rxconnp = cm_GetRxConn(connp); - code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume, - &volStat, &Name, &OfflineMsg, &MOTD); - rx_PutConnection(rxconnp); + rxconnp = cm_GetRxConn(connp); + code = RXAFS_GetVolumeStatus(rxconnp, scp->fid.volume, + &volStat, &Name, &OfflineMsg, &MOTD); + rx_PutConnection(rxconnp); - } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code)); - code = cm_MapRPCError(code, &req); + } while (cm_Analyze(connp, userp, &req, &scp->fid, NULL, 0, NULL, NULL, NULL, NULL, code)); + code = cm_MapRPCError(code, &req); + + if (code == 0 && volType == ROVOL) + { + + lock_ObtainWrite(&volp->rw); + volp->volumeSizeRO = volStat.BlocksInUse * 1024; + _InterlockedOr(&volp->flags, CM_VOLUMEFLAG_RO_SIZE_VALID); + lock_ReleaseWrite(&volp->rw); + } + } } if (code == 0) { -- 2.39.5