if (desiredAccess == DELETE)
goto done_2;
+ /* Always allow reading attributes (Hidden, System, Readonly, ...) */
+ if (desiredAccess == FILE_READ_ATTRIBUTES)
+ goto done_2;
+
if (desiredAccess & (AFS_ACCESS_READ|AFS_ACCESS_EXECUTE))
rights |= (scp->fileType == CM_SCACHETYPE_DIRECTORY ? PRSFS_LOOKUP : PRSFS_READ);
return code;
}
-int cm_ExpandSysName(clientchar_t *inp, clientchar_t *outp, long outSizeCch, unsigned int index)
+int cm_ExpandSysName(cm_req_t * reqp, clientchar_t *inp, clientchar_t *outp, long outSizeCch, unsigned int index)
{
clientchar_t *tp;
int prefixCount;
+#ifdef _WIN64
+ int use_sysname64 = 0;
+
+ if (cm_sysName64Count > 0 && reqp && (reqp->flags & CM_REQ_WOW64) && (reqp->flags & CM_REQ_SOURCE_REDIR))
+ use_sysname64 = 1;
+#endif
tp = cm_ClientStrRChr(inp, '@');
if (tp == NULL)
if (outp == NULL)
return 1;
+#ifdef _WIN64
+ if (use_sysname64 && index >= cm_sysName64Count)
+ return -1;
+ else
+#endif
if (index >= cm_sysNameCount)
return -1;
prefixCount = (int)(tp - inp);
cm_ClientStrCpyN(outp, outSizeCch, inp, prefixCount); /* copy out "a." from "a.@sys" */
- outp[prefixCount] = 0; /* null terminate the "a." */
- cm_ClientStrCat(outp, outSizeCch, cm_sysNameList[index]);/* append i386_nt40 */
+ outp[prefixCount] = 0; /* null terminate the "a." */
+#ifdef _WIN64
+ if (use_sysname64)
+ cm_ClientStrCat(outp, outSizeCch, cm_sysName64List[index]);
+ else
+#endif
+ cm_ClientStrCat(outp, outSizeCch, cm_sysNameList[index]);
+
return 1;
}
return cm_EvaluateVolumeReference(namep, flags, userp, reqp, outScpp);
}
- if (cm_ExpandSysName(namep, NULL, 0, 0) > 0) {
+ if (cm_ExpandSysName(reqp, namep, NULL, 0, 0) > 0) {
for ( sysNameIndex = 0; sysNameIndex < MAXNUMSYSNAMES; sysNameIndex++) {
- code = cm_ExpandSysName(namep, tname, lengthof(tname), sysNameIndex);
+ code = cm_ExpandSysName(reqp, namep, tname, lengthof(tname), sysNameIndex);
if (code > 0) {
code = cm_LookupInternal(dscp, tname, flags, userp, reqp, &scp);
#ifdef DEBUG_REFCOUNT
cm_dnlcRemove(dscp, cnamep);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &newDirStatus, &volSync, userp, reqp, CM_MERGEFLAG_DIROP);
+ if (RDR_Initialized &&
+ scp->fileType != CM_SCACHETYPE_FILE && scp->fileType != CM_SCACHETYPE_DIRECTORY)
+ RDR_InvalidateObject(dscp->fid.cell, dscp->fid.volume, dscp->fid.vnode,
+ dscp->fid.unique, dscp->fid.hash,
+ dscp->fileType, AFS_INVALIDATE_DATA_VERSION);
} else if (code == CM_ERROR_NOSUCHFILE) {
/* windows would not have allowed the request to delete the file
* if it did not believe the file existed. therefore, we must
}
cm_DiscardSCache(scp);
lock_ReleaseWrite(&scp->rw);
+ if (RDR_Initialized && !(reqp->flags & CM_REQ_SOURCE_REDIR) &&
+ !RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode,
+ scp->fid.unique, scp->fid.hash,
+ scp->fileType, AFS_INVALIDATE_DELETED))
+ buf_ClearRDRFlag(scp, "unlink");
}
}
/* can't create names with @sys in them; must expand it manually first.
* return "invalid request" if they try.
*/
- if (cm_ExpandSysName(cnamep, NULL, 0, 0)) {
+ if (cm_ExpandSysName(NULL, cnamep, NULL, 0, 0)) {
return CM_ERROR_ATSYS;
}
/* can't create names with @sys in them; must expand it manually first.
* return "invalid request" if they try.
*/
- if (cm_ExpandSysName(cnamep, NULL, 0, 0)) {
+ if (cm_ExpandSysName(NULL, cnamep, NULL, 0, 0)) {
return CM_ERROR_ATSYS;
}
lock_ObtainWrite(&dscp->rw);
if (code == 0) {
cm_MergeStatus(NULL, dscp, &updatedDirStatus, &volSync, userp, reqp, CM_MERGEFLAG_DIROP);
+ if (RDR_Initialized)
+ RDR_InvalidateObject(dscp->fid.cell, dscp->fid.volume, dscp->fid.vnode,
+ dscp->fid.unique, dscp->fid.hash,
+ dscp->fileType, AFS_INVALIDATE_DATA_VERSION);
}
cm_SyncOpDone(dscp, NULL, CM_SCACHESYNC_STOREDATA);
lock_ReleaseWrite(&dscp->rw);
cm_RemoveSCacheFromHashTable(scp);
lock_ReleaseWrite(&cm_scacheLock);
lock_ReleaseWrite(&scp->rw);
+ if (RDR_Initialized && !(reqp->flags & CM_REQ_SOURCE_REDIR) &&
+ !RDR_InvalidateObject(scp->fid.cell, scp->fid.volume, scp->fid.vnode,
+ scp->fid.unique, scp->fid.hash,
+ scp->fileType, AFS_INVALIDATE_DELETED))
+ buf_ClearRDRFlag(scp, "rmdir");
}
}
goto done;
}
- code = cm_Lookup(newDscp, cNewNamep, CM_FLAG_CASEFOLD, userp, reqp, &newScp);
- if (code == 0) {
- /* found a matching object with the new name */
- if (cm_FidCmp(&oldScp->fid, &newScp->fid)) {
- /* and they don't match so return an error */
- osi_Log2(afsd_logp, "cm_Rename newDscp 0x%p cNewName %S new name already exists",
- newDscp, osi_LogSaveStringW(afsd_logp, cNewNamep));
+ /* Case sensitive lookup. If this succeeds we are done. */
+ code = cm_Lookup(newDscp, cNewNamep, 0, userp, reqp, &newScp);
+ if (code) {
+ /*
+ * Case insensitive lookup. If this succeeds, it could have found the
+ * same file with a name that differs only by case or it could be a
+ * different file entirely.
+ */
+ code = cm_Lookup(newDscp, cNewNamep, CM_FLAG_CASEFOLD, userp, reqp, &newScp);
+ if (code == 0) {
+ /* found a matching object with the new name */
+ if (cm_FidCmp(&oldScp->fid, &newScp->fid)) {
+ /* and they don't match so return an error */
+ osi_Log2(afsd_logp, "cm_Rename newDscp 0x%p cNewName %S new name already exists",
+ newDscp, osi_LogSaveStringW(afsd_logp, cNewNamep));
+ code = CM_ERROR_EXISTS;
+ }
+ cm_ReleaseSCache(newScp);
+ newScp = NULL;
+ } else if (code == CM_ERROR_AMBIGUOUS_FILENAME) {
code = CM_ERROR_EXISTS;
}
- cm_ReleaseSCache(newScp);
- newScp = NULL;
- } else if (code == CM_ERROR_AMBIGUOUS_FILENAME) {
- code = CM_ERROR_EXISTS;
- } else {
- code = 0;
}
/* Check for RO volume */
cm_DiscardSCache(oldScp);
lock_ReleaseWrite(&oldScp->rw);
+ if (RDR_Initialized)
+ RDR_InvalidateObject(oldScp->fid.cell, oldScp->fid.volume, oldScp->fid.vnode, oldScp->fid.unique,
+ oldScp->fid.hash, oldScp->fileType, AFS_INVALIDATE_CALLBACK);
done:
if (oldScp)
cm_ReleaseSCache(oldScp);
fileLock->flags |= CM_FILELOCK_FLAG_DELETED;
+ cm_ReleaseUser(fileLock->userp);
+ cm_ReleaseSCacheNoLock(scp);
+
+ fileLock->userp = NULL;
+ fileLock->scp = NULL;
+
n_unlocks++;
}
}
return 0;
}
- osi_Log1(afsd_logp, "cm_UnlockByKey done with %d locks", n_unlocks);
-
+ code = cm_IntUnlock(scp, userp, reqp);
osi_Log1(afsd_logp, "cm_UnlockByKey code 0x%x", code);
+
osi_Log4(afsd_logp, " Leaving scp with excl[%d], shared[%d], client[%d], serverLock[%d]",
scp->exclusiveLocks, scp->sharedLocks, scp->clientLocks,
(int)(signed char) scp->serverLock);
return code;
}
+/* Called with scp->rw held */
long cm_Unlock(cm_scache_t *scp,
unsigned char sLockType,
LARGE_INTEGER LOffset, LARGE_INTEGER LLength,
}
fileLock->flags |= CM_FILELOCK_FLAG_DELETED;
+
+ if (userp != NULL) {
+ cm_ReleaseUser(fileLock->userp);
+ } else {
+ userp = fileLock->userp;
+ release_userp = TRUE;
+ }
+ cm_ReleaseSCacheNoLock(scp);
+ fileLock->userp = NULL;
+ fileLock->scp = NULL;
lock_ReleaseWrite(&cm_scacheLock);
+ code = cm_IntUnlock(scp, userp, reqp);
+
if (release_userp) {
cm_ReleaseUser(userp);
release_userp = FALSE;
fileLock->userp = NULL;
fileLock->scp = NULL;
- lock_ReleaseWrite(&cm_scacheLock);
- lock_ObtainWrite(&scp->rw);
- code = cm_IntUnlock(scp, userp, &req);
- lock_ReleaseWrite(&scp->rw);
-
- cm_ReleaseUser(fileLock->userp);
- lock_ObtainWrite(&cm_scacheLock);
- cm_ReleaseSCacheNoLock(scp);
+ if (scp && userp) {
+ lock_ReleaseWrite(&cm_scacheLock);
+ lock_ObtainWrite(&scp->rw);
+ code = cm_IntUnlock(scp, userp, &req);
+ lock_ReleaseWrite(&scp->rw);
+ cm_ReleaseUser(userp);
+ lock_ObtainWrite(&cm_scacheLock);
+ cm_ReleaseSCacheNoLock(scp);
+ }
osi_QRemove(&cm_allFileLocks, q);
cm_PutFileLock(fileLock);
int cm_KeyEquals(cm_key_t *k1, cm_key_t *k2, int flags)
{
return (k1->session_id == k2->session_id) && (k1->file_id == k2->file_id) &&
- ((flags & CM_UNLOCK_BY_FID) || (k1->process_id == k2->process_id));
+ ((flags & CM_UNLOCK_FLAG_BY_FID) || (k1->process_id == k2->process_id));
}
void cm_ReleaseAllLocks(void)