Windows: add 'locked' flag to cm_FSync and call when dropping write locks
authorJeffrey Altman <jaltman@your-file-system.com>
Wed, 28 Apr 2010 16:21:00 +0000 (12:21 -0400)
committerJeffrey Altman <jaltman@openafs.org>
Sun, 2 May 2010 17:38:11 +0000 (10:38 -0700)
cm_FSync should be called when releasing file server write locks.
This ensures that all dirty buffers are stored before the lock
can be acquired by another client.

Since cm_Unlock holds the cm_scache_t->rw exclusively when calling
cm_FSync, add a 'locked' parameter to cm_FSync to avoid an unnecessary
release and reacquire of the rwlock.

LICENSE MIT

Change-Id: I70bbeffc24ec4238461281bab4006b3a57b275e2
Reviewed-on: http://gerrit.openafs.org/1876
Tested-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Tested-by: Asanka Herath <asanka@secure-endpoints.com>
Reviewed-by: Asanka Herath <asanka@secure-endpoints.com>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>

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

index e403323..2994f91 100644 (file)
@@ -2804,10 +2804,16 @@ long cm_Create(cm_scache_t *dscp, clientchar_t *cnamep, long flags, cm_attr_t *a
     return code;
 }       
 
-long cm_FSync(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
+/*
+ * locked if TRUE means write-locked
+ * else the cm_scache_t rw must not be held
+ */
+long cm_FSync(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp, afs_uint32 locked)
 {
     long code;
 
+    if (locked)
+        lock_ReleaseWrite(&scp->rw);
     code = buf_CleanVnode(scp, userp, reqp);
     if (code == 0) {
         lock_ObtainWrite(&scp->rw);
@@ -2822,7 +2828,10 @@ long cm_FSync(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp)
            scp->flags &= ~(CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE);
        }
 
-        lock_ReleaseWrite(&scp->rw);
+        if (!locked)
+            lock_ReleaseWrite(&scp->rw);
+    } else if (locked) {
+        lock_ObtainWrite(&scp->rw);
     }
     return code;
 }
@@ -4847,10 +4856,12 @@ long cm_UnlockByKey(cm_scache_t * scp,
     if (scp->serverLock == LockWrite &&
         scp->exclusiveLocks == 0 &&
         scp->sharedLocks > 0) {
-
         /* The serverLock should be downgraded to LockRead */
         osi_Log0(afsd_logp, "  DOWNGRADE lock from LockWrite to LockRead");
 
+        /* Make sure there are no dirty buffers left. */
+        code = cm_FSync(scp, userp, reqp, TRUE);
+
         /* since scp->serverLock looked sane, we are going to assume
            that we have a valid server lock. */
         scp->lockDataVersion = scp->dataVersion;
@@ -4902,6 +4913,11 @@ long cm_UnlockByKey(cm_scache_t * scp,
               scp->sharedLocks == 0) {
         /* The serverLock should be released entirely */
 
+        if (scp->serverLock == LockWrite) {
+            /* Make sure there are no dirty buffers left. */
+            code = cm_FSync(scp, userp, reqp, TRUE);
+        }
+
         code = cm_IntReleaseLock(scp, userp, reqp);
 
         if (code == 0)
@@ -5052,6 +5068,9 @@ long cm_Unlock(cm_scache_t *scp,
         /* The serverLock should be downgraded to LockRead */
         osi_Log0(afsd_logp, "  DOWNGRADE lock from LockWrite to LockRead");
 
+        /* Make sure there are no dirty buffers left. */
+        code = cm_FSync(scp, userp, reqp, TRUE);
+
         /* Since we already had a lock, we assume that there is a
            valid server lock. */
         scp->lockDataVersion = scp->dataVersion;
@@ -5116,6 +5135,11 @@ long cm_Unlock(cm_scache_t *scp,
               scp->sharedLocks == 0) {
         /* The serverLock should be released entirely */
 
+        if (scp->serverLock == LockWrite) {
+            /* Make sure there are no dirty buffers left. */
+            code = cm_FSync(scp, userp, reqp, TRUE);
+        }
+
         code = cm_IntReleaseLock(scp, userp, reqp);
 
         if (code == 0) {
index 0c3a8a4..da22ded 100644 (file)
@@ -110,7 +110,7 @@ extern long cm_Create(cm_scache_t *scp, clientchar_t *namep, long flags,
                       cm_attr_t *attrp, cm_scache_t **scpp,
                       cm_user_t *userp, cm_req_t *reqp);
 
-extern long cm_FSync(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp);
+extern long cm_FSync(cm_scache_t *scp, cm_user_t *userp, cm_req_t *reqp, afs_uint32 locked);
 
 extern void cm_StatusFromAttr(struct AFSStoreStatus *statusp,
                               struct cm_scache *scp, struct cm_attr *attrp);
index 154964d..8a86680 100644 (file)
@@ -6686,7 +6686,7 @@ long smb_ReceiveCoreFlush(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
         cm_scache_t * scp = fidp->scp;
         cm_HoldSCache(scp);
         lock_ReleaseMutex(&fidp->mx);
-        code = cm_FSync(scp, userp, &req);
+        code = cm_FSync(scp, userp, &req, FALSE);
         cm_ReleaseSCache(scp);
     } else {
         lock_ReleaseMutex(&fidp->mx);
@@ -6834,7 +6834,7 @@ long smb_CloseFID(smb_vc_t *vcp, smb_fid_t *fidp, cm_user_t *userp,
         }
         if (smb_AsyncStore != 2) {
             lock_ReleaseMutex(&fidp->mx);
-            code = cm_FSync(scp, userp, &req);
+            code = cm_FSync(scp, userp, &req, FALSE);
             lock_ObtainMutex(&fidp->mx);
         }
     }