From 7f742f45a2aaa9dcb400aa1dc35ce617876fe7fd Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 9 Oct 2010 03:06:07 -0400 Subject: [PATCH] Windows: Do not issue RXAFS change RPCs on known RO volumes If the cm_scache_t is known to be on a RO volume, do not permit RXAFS_xxx RPCs that would attempt to make a change to the volume to be issued to the file server. Instead, return CM_ERROR_READONLY immediately. This avoids triggering the abort threshold for the current connection on the file server. LICENSE MIT Change-Id: I9c917e60277d281e32e4609d89b541803824251f Reviewed-on: http://gerrit.openafs.org/2950 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/cm_vnodeops.c | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 22b1caff5..b1668d1e7 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -1629,6 +1629,14 @@ long cm_Unlink(cm_scache_t *dscp, fschar_t *fnamep, clientchar_t * cnamep, #endif code = cm_Lookup(dscp, cnamep, CM_FLAG_NOMOUNTCHASE, userp, reqp, &scp); + if (code) + goto done; + + /* Check for RO volume */ + if (dscp->flags & CM_SCACHEFLAG_RO) { + code = CM_ERROR_READONLY; + goto done; + } /* make sure we don't screw up the dir status during the merge */ code = cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, @@ -2725,6 +2733,13 @@ long cm_SetAttr(cm_scache_t *scp, cm_attr_t *attrp, cm_user_t *userp, return cm_SetLength(scp, &attrp->length, userp, reqp); lock_ObtainWrite(&scp->rw); + /* Check for RO volume */ + if (scp->flags & CM_SCACHEFLAG_RO) { + code = CM_ERROR_READONLY; + lock_ReleaseWrite(&scp->rw); + return code; + } + /* otherwise, we have to make an RPC to get the status */ code = cm_SyncOp(scp, NULL, userp, reqp, 0, CM_SCACHESYNC_STORESTATUS); if (code) { @@ -2816,6 +2831,10 @@ long cm_Create(cm_scache_t *dscp, clientchar_t *cnamep, long flags, cm_attr_t *a } #endif /* AFS_FREELANCE_CLIENT */ + /* Check for RO volume */ + if (dscp->flags & CM_SCACHEFLAG_RO) + return CM_ERROR_READONLY; + /* before starting the RPC, mark that we're changing the file data, so * that someone who does a chmod will know to wait until our call * completes. @@ -2994,6 +3013,10 @@ long cm_MakeDir(cm_scache_t *dscp, clientchar_t *cnamep, long flags, cm_attr_t * } #endif /* AFS_FREELANCE_CLIENT */ + /* Check for RO volume */ + if (dscp->flags & CM_SCACHEFLAG_RO) + return CM_ERROR_READONLY; + /* before starting the RPC, mark that we're changing the directory * data, so that someone who does a chmod on the dir will wait until * our call completes. @@ -3121,6 +3144,10 @@ long cm_Link(cm_scache_t *dscp, clientchar_t *cnamep, cm_scache_t *sscp, long fl return CM_ERROR_CROSSDEVLINK; } + /* Check for RO volume */ + if (dscp->flags & CM_SCACHEFLAG_RO) + return CM_ERROR_READONLY; + cm_BeginDirOp(dscp, userp, reqp, CM_DIRLOCK_NONE, CM_DIROP_FLAG_NONE, &dirop); lock_ObtainWrite(&dscp->rw); @@ -3214,6 +3241,10 @@ long cm_SymLink(cm_scache_t *dscp, clientchar_t *cnamep, fschar_t *contentsp, lo cm_dirOp_t dirop; fschar_t *fnamep = NULL; + /* Check for RO volume */ + if (dscp->flags & CM_SCACHEFLAG_RO) + return CM_ERROR_READONLY; + memset(&volSync, 0, sizeof(volSync)); /* before starting the RPC, mark that we're changing the directory data, @@ -3363,6 +3394,12 @@ long cm_RemoveDir(cm_scache_t *dscp, fschar_t *fnamep, clientchar_t *cnamep, cm_ if (code) goto done; + /* Check for RO volume */ + if (dscp->flags & CM_SCACHEFLAG_RO) { + code = CM_ERROR_READONLY; + goto done; + } + /* before starting the RPC, mark that we're changing the directory data, * so that someone who does a chmod on the dir will wait until our * call completes. @@ -3541,6 +3578,13 @@ long cm_Rename(cm_scache_t *oldDscp, fschar_t *oldNamep, clientchar_t *cOldNamep } else { code = 0; } + + /* Check for RO volume */ + if (code == 0 && + (oldDscp->flags & CM_SCACHEFLAG_RO) || (newDscp->flags & CM_SCACHEFLAG_RO)) { + code = CM_ERROR_READONLY; + } + if (code) goto done; -- 2.39.5