Windows: Ensure that cm_NameI errors are acted upon promptly
authorJeffrey Altman <jaltman@your-file-system.com>
Wed, 15 Sep 2010 23:06:22 +0000 (01:06 +0200)
committerJeffrey Altman <jaltman@openafs.org>
Sun, 3 Oct 2010 14:49:44 +0000 (07:49 -0700)
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>

src/WINNT/afsd/rpc_srvsvc.c
src/WINNT/afsd/smb.c
src/WINNT/afsd/smb3.c

index ceacc66..860ed30 100644 (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);
             }
         }
     }
index 79b7885..3a6e2c8 100644 (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 */
 
index 522f58d..18f494c 100644 (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;
@@ -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,