From ef19cea44c433ec7c1d214e8229b5fb4ea4b6ef6 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sun, 6 Apr 2008 14:33:12 +0000 Subject: [PATCH] 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. --- 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 6ada61bd2..25c88dde5 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -569,7 +569,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; @@ -583,9 +583,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); } @@ -600,9 +602,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; @@ -610,7 +612,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)); @@ -643,8 +645,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); } @@ -773,8 +778,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); } @@ -811,8 +819,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); } @@ -958,8 +969,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); } @@ -1071,8 +1085,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); } @@ -1109,8 +1126,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); } @@ -1153,8 +1173,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); } @@ -3062,8 +3085,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 2f81de0f1..5f75bf6cc 100644 --- a/src/WINNT/afsd/cm_scache.c +++ b/src/WINNT/afsd/cm_scache.c @@ -649,13 +649,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); @@ -904,10 +897,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)); @@ -934,10 +923,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 4281e1665..f362d0d41 100644 --- a/src/WINNT/afsd/cm_vnodeops.c +++ b/src/WINNT/afsd/cm_vnodeops.c @@ -899,8 +899,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; } @@ -915,8 +914,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; } @@ -942,8 +940,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; } @@ -1271,7 +1268,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; @@ -1315,13 +1313,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