From 26e489accbdcc3fee64f450bba7d58ba5e37d56c Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Tue, 24 Feb 2009 05:06:34 +0000 Subject: [PATCH] DEVEL15-windows-freelance-20090223 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. (cherry picked from commit 3c1f85820853e9143cab076d735f7d7c27aeaf62) --- src/WINNT/afsd/cm_callback.c | 2 +- src/WINNT/afsd/cm_freelance.c | 89 ++++++++++++++++++++++++++--------- src/WINNT/afsd/cm_vnodeops.c | 2 +- 3 files changed, 70 insertions(+), 23 deletions(-) diff --git a/src/WINNT/afsd/cm_callback.c b/src/WINNT/afsd/cm_callback.c index 32f59ab36..47da75930 100644 --- a/src/WINNT/afsd/cm_callback.c +++ b/src/WINNT/afsd/cm_callback.c @@ -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; } diff --git a/src/WINNT/afsd/cm_freelance.c b/src/WINNT/afsd/cm_freelance.c index f787309ef..4bdfaba42 100644 --- a/src/WINNT/afsd/cm_freelance.c +++ b/src/WINNT/afsd/cm_freelance.c @@ -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 diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index c16a88fa4..854657b70 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -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 -- 2.39.5