From 565ab7aa8e751c06d03c3ab0034915572c29ef7c Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 16 Sep 2010 01:06:22 +0200 Subject: [PATCH] Windows: Ensure that cm_NameI errors are acted upon promptly There are many cases in the SMB server where an error from cm_NameI() was either ignored or not acted upon until several other operations are performed that could result in the same error being repeated. This is a mistake which did not have negative side effects until additional checks for callback status were added recently. At present, if a CM_ERROR_ACCESS error is returned and ignored, subsequent attempts to operate on the same cm_scache_t will result in additional queries to the file server that will also end in an abort response. This can trigger the file server to delay responses to the client. This patchset ensures that all cm_NameI() errors are acted upon promptly. LICENSE MIT Change-Id: Ie334b624cc2b28f2c2a37787b5edef9d37cdb041 Reviewed-on: http://gerrit.openafs.org/2887 Tested-by: Jeffrey Altman Reviewed-by: Jeffrey Altman --- src/WINNT/afsd/rpc_srvsvc.c | 6 ++-- src/WINNT/afsd/smb.c | 7 ++++ src/WINNT/afsd/smb3.c | 67 +++++++++++++++++++++++++++---------- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/WINNT/afsd/rpc_srvsvc.c b/src/WINNT/afsd/rpc_srvsvc.c index ceacc66a5f..860ed30ff5 100644 --- a/src/WINNT/afsd/rpc_srvsvc.c +++ b/src/WINNT/afsd/rpc_srvsvc.c @@ -835,9 +835,11 @@ NET_API_STATUS NetrShareGetInfo( if (cblen) { code = cm_NameI(dscp, pathstr, CM_FLAG_FOLLOW, userp, NULL, &req, &scp); - if (code && code != CM_ERROR_NOACCESS) + if (code == CM_ERROR_NOSUCHFILE || + code == CM_ERROR_NOSUCHPATH || + code == CM_ERROR_BPLUS_NOMATCH) code = cm_NameI(dscp, pathstr, CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW, - userp, NULL, &req, &scp); + userp, NULL, &req, &scp); } } } diff --git a/src/WINNT/afsd/smb.c b/src/WINNT/afsd/smb.c index 79b78857f7..3a6e2c873b 100644 --- a/src/WINNT/afsd/smb.c +++ b/src/WINNT/afsd/smb.c @@ -5628,6 +5628,13 @@ long smb_ReceiveCoreGetFileAttributes(smb_vc_t *vcp, smb_packet_t *inp, smb_pack return code; } } + else if (code != CM_ERROR_NOSUCHFILE && + code != CM_ERROR_NOSUCHPATH && + code != CM_ERROR_BPLUS_NOMATCH) + { + cm_ReleaseUser(userp); + return code; + } } #endif /* SPECIAL_FOLDERS */ diff --git a/src/WINNT/afsd/smb3.c b/src/WINNT/afsd/smb3.c index 522f58d48f..18f494c95a 100644 --- a/src/WINNT/afsd/smb3.c +++ b/src/WINNT/afsd/smb3.c @@ -2822,9 +2822,12 @@ long smb_ReceiveTran2Open(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t *op) CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); if (code != 0) { - code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &dscp); + if (code == CM_ERROR_NOSUCHFILE || + code == CM_ERROR_NOSUCHPATH || + code == CM_ERROR_BPLUS_NOMATCH) + code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &dscp); cm_FreeSpace(spacep); if (code) { @@ -3455,9 +3458,14 @@ long smb_ReceiveTran2QPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet_t cm_FreeSpace(spacep); } - /* now do namei and stat, and copy out the info */ - code = cm_NameI(cm_RootSCachep(userp, &req), pathp, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); + if (code == 0 || + code == CM_ERROR_NOSUCHFILE || + code == CM_ERROR_NOSUCHPATH || + code == CM_ERROR_BPLUS_NOMATCH) { + /* now do namei and stat, and copy out the info */ + code = cm_NameI(cm_RootSCachep(userp, &req), pathp, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); + } if (code) { cm_ReleaseUser(userp); @@ -3779,9 +3787,15 @@ long smb_ReceiveTran2SetPathInfo(smb_vc_t *vcp, smb_tran2Packet_t *p, smb_packet cm_FreeSpace(spacep); } - /* now do namei and stat, and copy out the info */ - code = cm_NameI(cm_RootSCachep(userp, &req), pathp, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); + if (code == 0 || + code == CM_ERROR_NOSUCHFILE || + code == CM_ERROR_NOSUCHPATH || + code == CM_ERROR_BPLUS_NOMATCH) { + /* now do namei and stat, and copy out the info */ + code = cm_NameI(cm_RootSCachep(userp, &req), pathp, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); + } + if (code) { cm_ReleaseUser(userp); smb_SendTran2Error(vcp, p, opx, code); @@ -6260,9 +6274,12 @@ long smb_ReceiveV3OpenX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) #endif /* DFS_SUPPORT */ if (code != 0) { - code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, - CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, - userp, tidPathp, &req, &dscp); + if (code == CM_ERROR_NOSUCHFILE || + code == CM_ERROR_NOSUCHPATH || + code == CM_ERROR_BPLUS_NOMATCH) + code = cm_NameI(cm_RootSCachep(userp, &req), spacep->wdata, + CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, + userp, tidPathp, &req, &dscp); if (code) { cm_ReleaseUser(userp); return code; @@ -7578,13 +7595,13 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) cm_ReleaseSCache(dscp); cm_ReleaseUser(userp); free(realPathp); - if (baseFidp) + if (baseFidp) smb_ReleaseFID(baseFidp); return CM_ERROR_EXISTS; } } + /* we have both scp and dscp */ } - /* we have both scp and dscp */ } else { code = cm_NameI(baseDirp, realPathp, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); @@ -7605,6 +7622,17 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) /* we might have scp but not dscp */ } + if (code && + code != CM_ERROR_NOSUCHFILE && + code != CM_ERROR_NOSUCHPATH && + code != CM_ERROR_BPLUS_NOMATCH) { + cm_ReleaseUser(userp); + free(realPathp); + if (baseFidp) + smb_ReleaseFID(baseFidp); + return code; + } + if (scp) foundscp = TRUE; @@ -7644,6 +7672,9 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp) #endif /* DFS_SUPPORT */ if (code && + (code == CM_ERROR_NOSUCHFILE || + code == CM_ERROR_NOSUCHPATH || + code == CM_ERROR_BPLUS_NOMATCH) && (tp = cm_ClientStrRChr(spacep->wdata, '\\')) && (createDisp == FILE_CREATE) && (realDirFlag == 1)) { @@ -8444,8 +8475,7 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out return CM_ERROR_EXISTS; } } - } else - dscp = NULL; + } } else { code = cm_NameI(baseDirp, realPathp, CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD, userp, tidPathp, &req, &scp); @@ -8468,7 +8498,10 @@ long smb_ReceiveNTTranCreate(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *out if (code == 0) foundscp = TRUE; - if (code != 0 || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) { + if (code == CM_ERROR_NOSUCHFILE || + code == CM_ERROR_NOSUCHPATH || + code == CM_ERROR_BPLUS_NOMATCH || + (code == 0 && (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE)))) { /* look up parent directory */ if ( !dscp ) { code = cm_NameI(baseDirp, spacep->wdata,