windows-freelance-20090223
authorJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 24 Feb 2009 05:06:23 +0000 (05:06 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 24 Feb 2009 05:06:23 +0000 (05:06 +0000)
LICENSE MIT

Fix another set of edge cases where adding a mountpoint or symlink
to the Freelance volume would result in the wrong fid being returned
to the request that made the addition.

When the Freelance directory is updated, invalidate the cm_scache_t object.
that is associated with it.

Actually use the data version when checking callback status.

The return value from Add Mount/Symlink is not negative on failure.
Its an actual error code.  Treat it that way.

src/WINNT/afsd/cm_callback.c
src/WINNT/afsd/cm_freelance.c
src/WINNT/afsd/cm_vnodeops.c

index 32f59ab..47da759 100644 (file)
@@ -1537,7 +1537,7 @@ int cm_HaveCallback(cm_scache_t *scp)
                 lock_ObtainWrite(&scp->rw);      // now get the lock back 
                 return 0;
             }
-            return 1;                  // no change
+            return (cm_data.fakeDirVersion == scp->dataVersion);
         }
         return 0;
     }
index f787309..4bdfaba 100644 (file)
@@ -387,8 +387,11 @@ int cm_reInitLocalMountPoints() {
 
     lock_ObtainWrite(&cm_scacheLock);
     lock_ObtainMutex(&cm_Freelance_Lock);  /* always scache then freelance lock */
-    for (i=1; i<=cm_noLocalMountPoints; i++) {
-        cm_SetFid(&aFid, AFS_FAKE_ROOT_CELL_ID, AFS_FAKE_ROOT_VOL_ID, i*2, i);
+    for (i=0; i<=cm_noLocalMountPoints; i++) {
+        if (i == 0)
+            cm_SetFid(&aFid, AFS_FAKE_ROOT_CELL_ID, AFS_FAKE_ROOT_VOL_ID, 1, 1);
+        else
+            cm_SetFid(&aFid, AFS_FAKE_ROOT_CELL_ID, AFS_FAKE_ROOT_VOL_ID, i*2, i);
         hash = CM_SCACHE_HASH(&aFid);
         for (scp=cm_data.scacheHashTablep[hash]; scp; scp=scp->nextp) {
             if (scp != cm_data.rootSCachep && cm_FidCmp(&scp->fid, &aFid) == 0) {
@@ -1063,12 +1066,33 @@ long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw,
             fprintf(fp, "%s#%s:%s\n", filename, fullname, volume);
         fclose(fp);
     }
+
+    /* Do this while we are holding the lock */
+    cm_data.fakeDirVersion++;
+    cm_localMountPointChangeFlag = 1;
     lock_ReleaseMutex(&cm_Freelance_Lock);
 
-    /* cm_reInitLocalMountPoints(); */
-    if (fidp)
-        cm_SetFid(fidp, fidp->cell, fidp->volume, ++cm_noLocalMountPoints*2, cm_noLocalMountPoints);
-    cm_noteLocalMountPointChange();
+    if (fidp) {
+        cm_req_t req;
+        afs_uint32 code;
+        cm_scache_t *scp;
+        clientchar_t *cpath;
+
+        cm_InitReq(&req);
+
+        cpath = cm_FsStringToClientStringAlloc(filename, -1, NULL);        
+        if (!cpath)
+            return CM_ERROR_NOSUCHPATH;
+        code = cm_NameI(cm_data.rootSCachep, filename,
+                        CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD | CM_FLAG_DFS_REFERRAL,
+                        cm_rootUserp, NULL, &req, &scp);
+        free(cpath);
+        if (code)
+            return code;
+        *fidp = scp->fid;
+        cm_ReleaseSCache(scp);
+    }
+    
     return 0;
 }
 
@@ -1170,13 +1194,14 @@ long cm_FreelanceRemoveMount(char *toremove)
             rename(hfile2, hfile);
         }
     }
-    
-    lock_ReleaseMutex(&cm_Freelance_Lock);
+
     if (found) {
-        cm_noteLocalMountPointChange();
-        return 0;
-    } else
-        return CM_ERROR_NOSUCHFILE;
+        /* Do this while we are holding the lock */
+        cm_data.fakeDirVersion++;
+        cm_localMountPointChangeFlag = 1;
+    }
+    lock_ReleaseMutex(&cm_Freelance_Lock);
+    return (found ? 0 : CM_ERROR_NOSUCHFILE);
 }
 
 long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp)
@@ -1270,12 +1295,33 @@ long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp)
         }
         RegCloseKey(hkFreelanceSymlinks);
     } 
+
+    /* Do this while we are holding the lock */
+    cm_data.fakeDirVersion++;
+    cm_localMountPointChangeFlag = 1;
     lock_ReleaseMutex(&cm_Freelance_Lock);
 
-    /* cm_reInitLocalMountPoints(); */
-    if (fidp)
-        cm_SetFid(fidp, fidp->cell, fidp->volume, ++cm_noLocalMountPoints*2, cm_noLocalMountPoints);
-    cm_noteLocalMountPointChange();
+    if (fidp) {
+        cm_req_t req;
+        afs_uint32 code;
+        cm_scache_t *scp;
+        clientchar_t *cpath;
+
+        cm_InitReq(&req);
+
+        cpath = cm_FsStringToClientStringAlloc(filename, -1, NULL);        
+        if (!cpath)
+            return CM_ERROR_NOSUCHPATH;
+        code = cm_NameI(cm_data.rootSCachep, filename,
+                        CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD | CM_FLAG_DFS_REFERRAL,
+                        cm_rootUserp, NULL, &req, &scp);
+        free(cpath);
+        if (code)
+            return code;
+        *fidp = scp->fid;
+        cm_ReleaseSCache(scp);
+    }
+
     return 0;
 }
 
@@ -1332,12 +1378,13 @@ long cm_FreelanceRemoveSymlink(char *toremove)
         RegCloseKey(hkFreelanceSymlinks);
     }
     
-    lock_ReleaseMutex(&cm_Freelance_Lock);
     if (found) {
-        cm_noteLocalMountPointChange();
-        return 0;
-    } else
-        return CM_ERROR_NOSUCHFILE;
+        /* Do this while we are holding the lock */
+        cm_data.fakeDirVersion++;
+        cm_localMountPointChangeFlag = 1;
+    }
+    lock_ReleaseMutex(&cm_Freelance_Lock);
+    return (found ? 0 : CM_ERROR_NOSUCHFILE);
 }
 
 long
index c16a88f..854657b 100644 (file)
@@ -1188,7 +1188,7 @@ long cm_LookupInternal(cm_scache_t *dscp, clientchar_t *cnamep, long flags, cm_u
                         code = cm_FreelanceAddSymlink(fnamep, fullname, &rock.fid);
                 }
             }
-            if (!found || code < 0) {   /* add mount point failed, so give up */
+            if (!found || code) {   /* add mount point failed, so give up */
                 if (flags & CM_FLAG_CHECKPATH)
                     code = CM_ERROR_NOSUCHPATH;
                 else