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 <jaltman@openafs.org>
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
This commit is contained in:
Jeffrey Altman 2010-09-16 01:06:22 +02:00 committed by Jeffrey Altman
parent 6ad0e5b529
commit 565ab7aa8e
3 changed files with 61 additions and 19 deletions

View File

@ -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);
}
}
}

View File

@ -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 */

View File

@ -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;
@ -7583,8 +7600,8 @@ long smb_ReceiveNTCreateX(smb_vc_t *vcp, smb_packet_t *inp, smb_packet_t *outp)
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,