From c7afb01bcebfdddbaed6c83b2c1e9ae793fdf7b3 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sun, 6 Apr 2008 14:37:22 +0000 Subject: [PATCH] DEVEL15-windows-fid-hash-20080406 LICENSE MIT 1. During the conversion to hash based FID comparisons the cm_GetSCache() lookups from the cm_ioctl.c (CM_IOCTL_QOPTS_HAVE_FID) and from FIDs returned by cm_LookupSearchProc() were broken. 2. In cm_LookupInternal(), ensure that an error is returned if rock.found is FALSE. A failure to return an error was resulting in cm_GetSCache() producing an object for FIDs with vnode=0,unique=0 3. cm_GetSCache(), remove the warning check for vnode=0,unique=0 4. reapply the synchronization logic to async store requests in cm_SyncOp(). The lack of synchronization is causing requests to complete out of order which is confusing the SMB redirector when under heavy load. (cherry picked from commit ef19cea44c433ec7c1d214e8229b5fb4ea4b6ef6) --- src/WINNT/afsd/cm_ioctl.c | 56 ++++++++++++++++++++++++++---------- src/WINNT/afsd/cm_scache.c | 15 ---------- src/WINNT/afsd/cm_vnodeops.c | 19 ++++++------ 3 files changed, 52 insertions(+), 38 deletions(-) diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index fcfc4d92b..ae3f0eaf7 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -587,7 +587,7 @@ long cm_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp) AFSFetchStatus fileStatus; AFSVolSync volSync; long code; - AFSFid fid; + AFSFid afid; int tlen; cm_req_t req; struct rx_connection * callp; @@ -601,9 +601,11 @@ long cm_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp) flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0); if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) { + cm_fid_t fid; cm_SkipIoctlPath(ioctlp); - - code = cm_GetSCache(&optionsp->fid, &scp, userp, &req); + cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume, + optionsp->fid.vnode, optionsp->fid.unique); + code = cm_GetSCache(&fid, &scp, userp, &req); } else { code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags); } @@ -618,9 +620,9 @@ long cm_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp) } else #endif { - fid.Volume = scp->fid.volume; - fid.Vnode = scp->fid.vnode; - fid.Unique = scp->fid.unique; + afid.Volume = scp->fid.volume; + afid.Vnode = scp->fid.vnode; + afid.Unique = scp->fid.unique; do { acl.AFSOpaque_val = ioctlp->outDatap; acl.AFSOpaque_len = 0; @@ -628,7 +630,7 @@ long cm_IoctlGetACL(smb_ioctl_t *ioctlp, cm_user_t *userp) if (code) continue; callp = cm_GetRxConn(connp); - code = RXAFS_FetchACL(callp, &fid, &acl, &fileStatus, &volSync); + code = RXAFS_FetchACL(callp, &afid, &acl, &fileStatus, &volSync); rx_PutConnection(callp); } while (cm_Analyze(connp, userp, &req, &scp->fid, &volSync, NULL, NULL, code)); @@ -661,8 +663,11 @@ long cm_IoctlGetFileCellName(struct smb_ioctl *ioctlp, struct cm_user *userp) flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0); if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) { + cm_fid_t fid; cm_SkipIoctlPath(ioctlp); - code = cm_GetSCache(&optionsp->fid, &scp, userp, &req); + cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume, + optionsp->fid.vnode, optionsp->fid.unique); + code = cm_GetSCache(&fid, &scp, userp, &req); } else { code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags); } @@ -791,8 +796,11 @@ long cm_IoctlFlushVolume(struct smb_ioctl *ioctlp, struct cm_user *userp) flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0); if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) { + cm_fid_t fid; cm_SkipIoctlPath(ioctlp); - code = cm_GetSCache(&optionsp->fid, &scp, userp, &req); + cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume, + optionsp->fid.vnode, optionsp->fid.unique); + code = cm_GetSCache(&fid, &scp, userp, &req); } else { code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags); } @@ -829,8 +837,11 @@ long cm_IoctlFlushFile(struct smb_ioctl *ioctlp, struct cm_user *userp) flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0); if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) { + cm_fid_t fid; cm_SkipIoctlPath(ioctlp); - code = cm_GetSCache(&optionsp->fid, &scp, userp, &req); + cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume, + optionsp->fid.vnode, optionsp->fid.unique); + code = cm_GetSCache(&fid, &scp, userp, &req); } else { code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags); } @@ -976,8 +987,11 @@ long cm_IoctlGetVolumeStatus(struct smb_ioctl *ioctlp, struct cm_user *userp) flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0); if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) { + cm_fid_t fid; cm_SkipIoctlPath(ioctlp); - code = cm_GetSCache(&optionsp->fid, &scp, userp, &req); + cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume, + optionsp->fid.vnode, optionsp->fid.unique); + code = cm_GetSCache(&fid, &scp, userp, &req); } else { code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags); } @@ -1089,8 +1103,11 @@ long cm_IoctlGetFileType(struct smb_ioctl *ioctlp, struct cm_user *userp) flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0); if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) { + cm_fid_t fid; cm_SkipIoctlPath(ioctlp); - code = cm_GetSCache(&optionsp->fid, &scp, userp, &req); + cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume, + optionsp->fid.vnode, optionsp->fid.unique); + code = cm_GetSCache(&fid, &scp, userp, &req); } else { code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags); } @@ -1127,8 +1144,11 @@ long cm_IoctlGetOwner(struct smb_ioctl *ioctlp, struct cm_user *userp) flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0); if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) { + cm_fid_t fid; cm_SkipIoctlPath(ioctlp); - code = cm_GetSCache(&optionsp->fid, &scp, userp, &req); + cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume, + optionsp->fid.vnode, optionsp->fid.unique); + code = cm_GetSCache(&fid, &scp, userp, &req); } else { code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags); } @@ -1171,8 +1191,11 @@ long cm_IoctlWhereIs(struct smb_ioctl *ioctlp, struct cm_user *userp) flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0); if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) { + cm_fid_t fid; cm_SkipIoctlPath(ioctlp); - code = cm_GetSCache(&optionsp->fid, &scp, userp, &req); + cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume, + optionsp->fid.vnode, optionsp->fid.unique); + code = cm_GetSCache(&fid, &scp, userp, &req); } else { code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags); } @@ -3112,8 +3135,11 @@ long cm_IoctlPathAvailability(struct smb_ioctl *ioctlp, struct cm_user *userp) flags |= (optionsp->literal ? CM_PARSE_FLAG_LITERAL : 0); if (optionsp && CM_IOCTL_QOPTS_HAVE_FID(optionsp)) { + cm_fid_t fid; cm_SkipIoctlPath(ioctlp); - code = cm_GetSCache(&optionsp->fid, &scp, userp, &req); + cm_SetFid(&fid, optionsp->fid.cell, optionsp->fid.volume, + optionsp->fid.vnode, optionsp->fid.unique); + code = cm_GetSCache(&fid, &scp, userp, &req); } else { code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp, flags); } diff --git a/src/WINNT/afsd/cm_scache.c b/src/WINNT/afsd/cm_scache.c index 9642c8a73..4a2235bc4 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -651,13 +651,6 @@ long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp, osi_assertx(fidp->cell != 0, "unassigned cell value"); - if (fidp->cell== cm_data.rootFid.cell && - fidp->volume==cm_data.rootFid.volume && - fidp->vnode==0x0 && fidp->unique==0x0) - { - osi_Log0(afsd_logp,"cm_GetSCache called with root cell/volume and vnode=0 and unique=0"); - } - // yj: check if we have the scp, if so, we don't need // to do anything else lock_ObtainWrite(&cm_scacheLock); @@ -906,10 +899,6 @@ void cm_SyncOpAddToWaitQueue(cm_scache_t * scp, afs_int32 flags, cm_buf_t * bufp { cm_scache_waiter_t * w; - /* Do not use the queue for asynchronous store operations */ - if (flags == CM_SCACHESYNC_ASYNCSTORE) - return; - lock_ObtainWrite(&cm_scacheLock); if (cm_allFreeWaiters == NULL) { w = malloc(sizeof(*w)); @@ -936,10 +925,6 @@ int cm_SyncOpCheckContinue(cm_scache_t * scp, afs_int32 flags, cm_buf_t * bufp) cm_scache_waiter_t * w; int this_is_me; - /* Do not use the queue for asynchronous store operations */ - if (flags == CM_SCACHESYNC_ASYNCSTORE) - return 1; - osi_Log0(afsd_logp, "cm_SyncOpCheckContinue checking for continuation"); lock_ObtainRead(&cm_scacheLock); diff --git a/src/WINNT/afsd/cm_vnodeops.c b/src/WINNT/afsd/cm_vnodeops.c index 6746c1c60..2ae418212 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -901,8 +901,7 @@ long cm_LookupSearchProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, sp->ExactFound = 1; if (!sp->caseFold || matchName == shortName) { - sp->fid.vnode = ntohl(dep->fid.vnode); - sp->fid.unique = ntohl(dep->fid.unique); + cm_SetFid(&sp->fid, sp->fid.cell, sp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique)); return CM_ERROR_STOPNOW; } @@ -917,8 +916,7 @@ long cm_LookupSearchProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, match = strcmp(matchName, sp->searchNamep); if (match == 0) { sp->ExactFound = 1; - sp->fid.vnode = ntohl(dep->fid.vnode); - sp->fid.unique = ntohl(dep->fid.unique); + cm_SetFid(&sp->fid, sp->fid.cell, sp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique)); return CM_ERROR_STOPNOW; } @@ -944,8 +942,7 @@ long cm_LookupSearchProc(cm_scache_t *scp, cm_dirEntry_t *dep, void *rockp, sp->NCfound = 1; inexact: - sp->fid.vnode = ntohl(dep->fid.vnode); - sp->fid.unique = ntohl(dep->fid.unique); + cm_SetFid(&sp->fid, sp->fid.cell, sp->fid.volume, ntohl(dep->fid.vnode), ntohl(dep->fid.unique)); return 0; } @@ -1273,7 +1270,8 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us } else if (!strchr(namep, '#') && !strchr(namep, '%') && strcmp(namep, "srvsvc") && strcmp(namep, "wkssvc") && - strcmp(namep, "ipc$")) { + strcmp(namep, "ipc$")) + { /* nonexistent dir on freelance root, so add it */ char fullname[200] = "."; int found = 0; @@ -1317,13 +1315,18 @@ long cm_LookupInternal(cm_scache_t *dscp, char *namep, long flags, cm_user_t *us return CM_ERROR_NOSUCHFILE; } tscp = NULL; /* to force call of cm_GetSCache */ + } else { + if (flags & CM_FLAG_CHECKPATH) + return CM_ERROR_NOSUCHPATH; + else + return CM_ERROR_NOSUCHFILE; } } haveFid: if ( !tscp ) /* we did not find it in the dnlc */ { - dnlcHit = 0; + dnlcHit = 0; code = cm_GetSCache(&rock.fid, &tscp, userp, reqp); if (code) return code; -- 2.39.5