[OpenAFS-devel] Windows SMB server returns CM_ERROR_NOSUCHFILE instead of CM_ERROR_NOSUCHPATH

Lantzer, Ryan lantzer@umr.edu
Tue, 4 Mar 2003 13:01:56 -0600


When MS Visual Studio 7.0 is used to create a new MFC C++ project on a
drive mapped to AFS, it generates an error "Error on creating file. File
already exists or cannot write to
<projectfolder>\res\<projectname>.rc2". The problem appears to be the
result of Visual Studio 7.0 trying to create a file
<projectfolder>\res\<projectname>.rc2 without first creating the folder
<projectfolder>\res. The Windows AFS client returns the error
ERROR_NOSUCHFILE, where the same request on a local NTFS volume returns
the error ERROR_NOSUCHPATH. The patch below applies the
CM_FLAG_CHECKPATH to what appears to be the offending call in
smb_ReceiveNTCreateX to cm_NameI so that it returns CM_ERROR_NOSUCHPATH
instead of CM_ERROR_NOSUCHFILE if the requested item is not found. This
call in smb_ReceiveNTCreateX to cm_NameI is called against the parent
directory of the requested file or directory, so if a parent folder is
not found, I think that CM_NOSUCHPATH should be returned in place of
CM_ERROR_NOSUCHFILE. I am not really an expert on SMB communications or
on AFS system calls like cm_NameI, but to me it looks like if we know
that we are running cm_NameI to find what should be a directory, then it
should not return CM_ERROR_NOSUCHFILE, and should return
CM_ERROR_NOSUCHPATH instead.

If anyone has a better understanding of why this problem is occurring or
a better idea on how it should be fixed, please let me know.

This patch should be applied to src\WINNT\afsd\smb3.c.

Ryan Lantzer

--- smb3.c.orig	2002-12-04 08:20:47.000000000 -0600
+++ smb3.c	2003-02-28 16:46:19.000000000 -0600
@@ -3136,7 +3136,7 @@
 	    || (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) {
 		/* look up parent directory */
 		code =3D cm_NameI(baseDirp, spacep->data,
-				CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
+				CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD |
CM_FLAG_CHECKPATH,
 				userp, tidPathp, &req, &dscp);
=20
 		if (baseFid !=3D 0) smb_ReleaseFID(baseFidp);