]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
[CIFS] work around bug in Samba server handling for posix open
authorSteve French <sfrench@us.ibm.com>
Wed, 4 Mar 2009 19:54:08 +0000 (19:54 +0000)
committerSteve French <sfrench@us.ibm.com>
Thu, 12 Mar 2009 01:36:21 +0000 (01:36 +0000)
Samba server (version 3.3.1 and earlier, and 3.2.8 and earlier) incorrectly
required the O_CREAT flag on posix open (even when a file was not being
created).  This disables posix open (create is still ok) after the first
attempt returns EINVAL (and logs an error, once, recommending that they
update their server).

Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
fs/cifs/CHANGES
fs/cifs/cifsglob.h
fs/cifs/file.c

index b33c8412e2c821ba8ad47ed4c4b37f59b0d325d6..fc977dfe95932b5130b900fb26f1f2170c8ab8c5 100644 (file)
@@ -11,6 +11,8 @@ to better ensure that we wait for server to write all of the data to
 server disk (not just write it over the network).  Add new mount
 parameter to allow user to disable sending the (slow) SMB flush on
 fsync if desired (fsync still flushes all cached write data to the server).
+Posix file open support added (turned off after one attempt if server
+fails to support it properly, as with Samba server versions prior to 3.3.2)
 
 Version 1.56
 ------------
index 44ff94d37e18f6c21e3c9fd0e8e6217e25085592..9fbf4dff5da6100b5a5ad902ec0384e1e18cac02 100644 (file)
@@ -299,6 +299,7 @@ struct cifsTconInfo {
        bool unix_ext:1;  /* if false disable Linux extensions to CIFS protocol
                                for this mount even if server would support */
        bool local_lease:1; /* check leases (only) on local system not remote */
+       bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
        bool need_reconnect:1; /* connection reset, tid now invalid */
        /* BB add field for back pointer to sb struct(s)? */
 };
index 7bef4cce572a6e3785c8eafa5b1f1e17ac819095..81747acca4c4774b48431eb0313d80d97ecc1c6c 100644 (file)
@@ -328,7 +328,8 @@ int cifs_open(struct inode *inode, struct file *file)
        else
                oplock = 0;
 
-       if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
+       if (!tcon->broken_posix_open && tcon->unix_ext &&
+           (tcon->ses->capabilities & CAP_UNIX) &&
            (CIFS_UNIX_POSIX_PATH_OPS_CAP &
                        le64_to_cpu(tcon->fsUnixInfo.Capability))) {
                int oflags = (int) cifs_posix_convert_flags(file->f_flags);
@@ -344,11 +345,20 @@ int cifs_open(struct inode *inode, struct file *file)
                        cifs_posix_open_inode_helper(inode, file, pCifsInode,
                                                     pCifsFile, oplock, netfid);
                        goto out;
+               } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
+                       if (tcon->ses->serverNOS)
+                               cERROR(1, ("server %s of type %s returned"
+                                          " unexpected error on SMB posix open"
+                                          ", disabling posix open support."
+                                          " Check if server update available.",
+                                          tcon->ses->serverName,
+                                          tcon->ses->serverNOS));
+                       tcon->broken_posix_open = true;
                } else if ((rc != -EIO) && (rc != -EREMOTE) &&
                         (rc != -EOPNOTSUPP)) /* path not found or net err */
                        goto out;
-               /* fallthrough to retry open the old way on operation
-                  not supported or DFS errors */
+               /* else fallthrough to retry open the old way on network i/o
+                  or DFS errors */
        }
 
        desiredAccess = cifs_convert_flags(file->f_flags);