Windows: Update root.afs scache dv when Freelance dir bufs are regenerated
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 31 Jul 2010 04:05:24 +0000 (00:05 -0400)
committerJeffrey Altman <jaltman@openafs.org>
Mon, 2 Aug 2010 16:26:46 +0000 (09:26 -0700)
When the contents of the Freelance root directory changes the fake
directory buffers are updated and a fakeDirVersion is incremented.
The dataVersion of the cm_scache_t object is supposed to be updated
on the next access by performing a fake get callback request.
Unfortunately, this did not always occur because of a race.  If another
Freelance object is updated first, the root directory object would
never successfully get a fake callback.

This patchset ensures that the generation of the fake directory
buffer content and the callback are obtained under the same set
of locks thereby removing the race.

LICENSE MIT

Change-Id: Ic8c77fc3c652cd056f84db55ca6db32499bcb0c9
Reviewed-on: http://gerrit.openafs.org/2490
Tested-by: Jeffrey Altman <jaltman@openafs.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>

src/WINNT/afsd/cm_freelance.c

index fb0be30..2868878 100644 (file)
@@ -408,6 +408,9 @@ int cm_reInitLocalMountPoints() {
     cm_fid_t aFid;
     unsigned int i, hash;
     cm_scache_t *scp, **lscpp, *tscp;
+    cm_req_t req;
+
+    cm_InitReq(&req);
        
     osi_Log0(afsd_logp,"----- freelance reinitialization starts ----- ");
 
@@ -456,8 +459,11 @@ int cm_reInitLocalMountPoints() {
         }
     }
     lock_ReleaseWrite(&cm_scacheLock);
+    lock_ReleaseMutex(&cm_Freelance_Lock);
     osi_Log0(afsd_logp,"\tall old scp cleared!");
 
+    lock_ObtainWrite(&cm_data.rootSCachep->rw);
+    lock_ObtainMutex(&cm_Freelance_Lock);
     // we must free the memory that was allocated in the prev
     // cm_InitLocalMountPoints call
     osi_Log0(afsd_logp,"Removing old localmountpoints...  ");
@@ -478,6 +484,9 @@ int cm_reInitLocalMountPoints() {
 
     lock_ReleaseMutex(&cm_Freelance_Lock);
 
+    cm_GetCallback(cm_data.rootSCachep, cm_rootUserp, &req, 0);
+    lock_ReleaseWrite(&cm_data.rootSCachep->rw);
+
     osi_Log0(afsd_logp,"----- freelance reinit complete -----");
     return 0;
 }