Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 23 May 2009 20:42:53 +0000 (13:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 23 May 2009 20:42:53 +0000 (13:42 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  [CIFS] Avoid open on possible directories since Samba now rejects them

fs/cifs/dir.c

index f49d684edd964038e0f8da6b783647137d8b66c3..3758965d73d56c8b281a3ea055b2eb27eed3892d 100644 (file)
@@ -657,31 +657,36 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
        }
        cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode));
 
+       /* Posix open is only called (at lookup time) for file create now.
+        * For opens (rather than creates), because we do not know if it
+        * is a file or directory yet, and current Samba no longer allows
+        * us to do posix open on dirs, we could end up wasting an open call
+        * on what turns out to be a dir. For file opens, we wait to call posix
+        * open till cifs_open.  It could be added here (lookup) in the future
+        * but the performance tradeoff of the extra network request when EISDIR
+        * or EACCES is returned would have to be weighed against the 50%
+        * reduction in network traffic in the other paths.
+        */
        if (pTcon->unix_ext) {
                if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
-                    (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open) {
-                       if (!((nd->intent.open.flags & O_CREAT) &&
-                                       (nd->intent.open.flags & O_EXCL))) {
-                               rc = cifs_posix_open(full_path, &newInode,
+                    (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
+                    (nd->intent.open.flags & O_CREAT)) {
+                       rc = cifs_posix_open(full_path, &newInode,
                                        parent_dir_inode->i_sb,
                                        nd->intent.open.create_mode,
                                        nd->intent.open.flags, &oplock,
                                        &fileHandle, xid);
-                               /*
-                                * This code works around a bug in
-                                * samba posix open in samba versions 3.3.1
-                                * and earlier where create works
-                                * but open fails with invalid parameter.
-                                * If either of these error codes are
-                                * returned, follow the normal lookup.
-                                * Otherwise, the error during posix open
-                                * is handled.
-                                */
-                               if ((rc != -EINVAL) && (rc != -EOPNOTSUPP))
-                                       posix_open = true;
-                               else
-                                       pTcon->broken_posix_open = true;
-                       }
+                       /*
+                        * The check below works around a bug in POSIX
+                        * open in samba versions 3.3.1 and earlier where
+                        * open could incorrectly fail with invalid parameter.
+                        * If either that or op not supported returned, follow
+                        * the normal lookup.
+                        */
+                       if ((rc == 0) || (rc == -ENOENT))
+                               posix_open = true;
+                       else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
+                               pTcon->broken_posix_open = true;
                }
                if (!posix_open)
                        rc = cifs_get_inode_info_unix(&newInode, full_path,