windows-freelance-20080407
authorJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 7 Apr 2008 06:42:44 +0000 (06:42 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Mon, 7 Apr 2008 06:42:44 +0000 (06:42 +0000)
LICENSE MIT

When freelance symlinks and mountpoints were modified the target string
value was not being updated and the old data was not being invalidated.

src/WINNT/afsd/cm_ioctl.c
src/WINNT/afsd/cm_scache.c

index 25c88dd..e0bbc86 100644 (file)
@@ -1304,44 +1304,51 @@ long cm_IoctlDeleteMountPoint(struct smb_ioctl *ioctlp, struct cm_user *userp)
     code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp);
         
     /* if something went wrong, bail out now */
-    if (code) {
-        goto done2;
-    }
+    if (code)
+        goto done3;
         
     lock_ObtainWrite(&scp->rw);
     code = cm_SyncOp(scp, NULL, userp, &req, 0,
                       CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-    if (code) {     
-        lock_ReleaseWrite(&scp->rw);
-        cm_ReleaseSCache(scp);
+    if (code)  
         goto done2;
-    }
 
     /* now check that this is a real mount point */
     if (scp->fileType != CM_SCACHETYPE_MOUNTPOINT) {
-        lock_ReleaseWrite(&scp->rw);
-        cm_ReleaseSCache(scp);
         code = CM_ERROR_INVAL;
         goto done1;
     }
 
     /* time to make the RPC, so drop the lock */
     lock_ReleaseWrite(&scp->rw);
-    cm_ReleaseSCache(scp);
 
-    /* easier to do it this way */
-    code = cm_Unlink(dscp, cp, userp, &req);
+#ifdef AFS_FREELANCE_CLIENT
+    if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
+        /* we are adding the mount point to the root dir., so call
+         * the freelance code to do the add. */
+        osi_Log0(afsd_logp,"IoctlDeleteMountPoint from Freelance root dir");
+        code = cm_FreelanceRemoveMount(cp);
+    } else 
+#endif
+    {
+        /* easier to do it this way */
+        code = cm_Unlink(dscp, cp, userp, &req);
+    }
     if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
         smb_NotifyChange(FILE_ACTION_REMOVED,
                           FILE_NOTIFY_CHANGE_DIR_NAME,
                           dscp, cp, NULL, TRUE);
 
-  done1:
     lock_ObtainWrite(&scp->rw);
+  done1:
     cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
-    lock_ReleaseWrite(&scp->rw);
 
   done2:
+    cm_DiscardSCache(scp);
+    lock_ReleaseWrite(&scp->rw);
+    cm_ReleaseSCache(scp);
+
+  done3:
     cm_ReleaseSCache(dscp);
     return code;
 }
@@ -2156,17 +2163,6 @@ long cm_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
 
     cp = ioctlp->inDatap;
 
-#ifdef AFS_FREELANCE_CLIENT
-    if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
-        /* we are adding the mount point to the root dir., so call
-         * the freelance code to do the add. */
-        osi_Log0(afsd_logp,"IoctlDeletelink from Freelance root dir");
-        code = cm_FreelanceRemoveSymlink(cp);
-       cm_ReleaseSCache(dscp);
-        return code;
-    }
-#endif
-
     code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp);
         
     /* if something went wrong, bail out now */
@@ -2190,8 +2186,18 @@ long cm_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
     /* time to make the RPC, so drop the lock */
     lock_ReleaseWrite(&scp->rw);
         
-    /* easier to do it this way */
-    code = cm_Unlink(dscp, cp, userp, &req);
+#ifdef AFS_FREELANCE_CLIENT
+    if (cm_freelanceEnabled && dscp == cm_data.rootSCachep) {
+        /* we are adding the mount point to the root dir., so call
+         * the freelance code to do the add. */
+        osi_Log0(afsd_logp,"IoctlDeletelink from Freelance root dir");
+        code = cm_FreelanceRemoveSymlink(cp);
+    } else 
+#endif
+    {
+        /* easier to do it this way */
+        code = cm_Unlink(dscp, cp, userp, &req);
+    }
     if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
         smb_NotifyChange(FILE_ACTION_REMOVED,
                           FILE_NOTIFY_CHANGE_FILE_NAME
@@ -2203,6 +2209,7 @@ long cm_IoctlDeletelink(struct smb_ioctl *ioctlp, struct cm_user *userp)
     cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
 
   done2:
+    cm_DiscardSCache(scp);
     lock_ReleaseWrite(&scp->rw);
     cm_ReleaseSCache(scp);
 
index 5f75bf6..70586b4 100644 (file)
@@ -637,7 +637,7 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
 #endif
 {
     long hash;
-    cm_scache_t *scp;
+    cm_scache_t *scp = NULL;
     long code;
     cm_volume_t *volp = NULL;
     cm_cell_t *cellp;
@@ -649,6 +649,15 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
         
     osi_assertx(fidp->cell != 0, "unassigned cell value");
 
+#ifdef AFS_FREELANCE_CLIENT
+    special = (fidp->cell==AFS_FAKE_ROOT_CELL_ID && 
+               fidp->volume==AFS_FAKE_ROOT_VOL_ID &&
+               !(fidp->vnode==0x1 && fidp->unique==0x1));
+    isRoot = (fidp->cell==AFS_FAKE_ROOT_CELL_ID && 
+              fidp->volume==AFS_FAKE_ROOT_VOL_ID &&
+              fidp->vnode==0x1 && fidp->unique==0x1);
+#endif
+
     // yj: check if we have the scp, if so, we don't need
     // to do anything else
     lock_ObtainWrite(&cm_scacheLock);
@@ -658,6 +667,11 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
            afsi_log("%s:%d cm_GetSCache (1) outScpp 0x%p ref %d", file, line, scp, scp->refCount);
            osi_Log1(afsd_logp,"cm_GetSCache (1) outScpp 0x%p", scp);
 #endif
+#ifdef AFS_FREELANCE_CLIENT
+            if (cm_freelanceEnabled && special && 
+                cm_data.fakeDirVersion != scp->dataVersion)
+                break;
+#endif
             cm_HoldSCacheNoLock(scp);
             *outScpp = scp;
             cm_AdjustScacheLRU(scp);
@@ -675,12 +689,6 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
     // because we have to fill in the status stuff 'coz we
     // don't want trybulkstat to fill it in for us
 #ifdef AFS_FREELANCE_CLIENT
-    special = (fidp->cell==AFS_FAKE_ROOT_CELL_ID && 
-               fidp->volume==AFS_FAKE_ROOT_VOL_ID &&
-               !(fidp->vnode==0x1 && fidp->unique==0x1));
-    isRoot = (fidp->cell==AFS_FAKE_ROOT_CELL_ID && 
-              fidp->volume==AFS_FAKE_ROOT_VOL_ID &&
-              fidp->vnode==0x1 && fidp->unique==0x1);
     if (cm_freelanceEnabled && isRoot) {
         osi_Log0(afsd_logp,"cm_GetSCache Freelance and isRoot");
         /* freelance: if we are trying to get the root scp for the first
@@ -694,6 +702,14 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
         afs_uint32 fileType;
 
         osi_Log0(afsd_logp,"cm_GetSCache Freelance and special");
+
+        if (cm_getLocalMountPointChange()) {   // check for changes
+            cm_clearLocalMountPointChange();    // clear the changefile
+                   lock_ReleaseWrite(&cm_scacheLock);
+            cm_reInitLocalMountPoints();       // start reinit
+                       lock_ObtainWrite(&cm_scacheLock);
+        }
+
         lock_ObtainMutex(&cm_Freelance_Lock);
         if (fidp->vnode >= 2 && fidp->vnode - 2 < cm_noLocalMountPoints) {
             strncpy(mp,(cm_localMountPoints+fidp->vnode-2)->mountPointStringp, MOUNTPOINTLEN);
@@ -708,7 +724,9 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
         }
         lock_ReleaseMutex(&cm_Freelance_Lock);
 
-        scp = cm_GetNewSCache();
+        if (scp == NULL) 
+            scp = cm_GetNewSCache();
+
        if (scp == NULL) {
            osi_Log0(afsd_logp,"cm_GetSCache unable to obtain *new* scache entry");
             lock_ReleaseWrite(&cm_scacheLock);