aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/file.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2009-03-04 14:54:08 -0500
committerSteve French <sfrench@us.ibm.com>2009-03-11 21:36:21 -0400
commit64cc2c63694a03393985ffc8b178e72f52dd8a06 (patch)
tree819161cd3f6b4268b5ff21dfb0c427496134fef5 /fs/cifs/file.c
parent276a74a4835ad86d6da42f3a084b060afc5656e8 (diff)
[CIFS] work around bug in Samba server handling for posix open
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>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r--fs/cifs/file.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 7bef4cce572a..81747acca4c4 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -328,7 +328,8 @@ int cifs_open(struct inode *inode, struct file *file)
328 else 328 else
329 oplock = 0; 329 oplock = 0;
330 330
331 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && 331 if (!tcon->broken_posix_open && tcon->unix_ext &&
332 (tcon->ses->capabilities & CAP_UNIX) &&
332 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 333 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
333 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 334 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
334 int oflags = (int) cifs_posix_convert_flags(file->f_flags); 335 int oflags = (int) cifs_posix_convert_flags(file->f_flags);
@@ -344,11 +345,20 @@ int cifs_open(struct inode *inode, struct file *file)
344 cifs_posix_open_inode_helper(inode, file, pCifsInode, 345 cifs_posix_open_inode_helper(inode, file, pCifsInode,
345 pCifsFile, oplock, netfid); 346 pCifsFile, oplock, netfid);
346 goto out; 347 goto out;
348 } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
349 if (tcon->ses->serverNOS)
350 cERROR(1, ("server %s of type %s returned"
351 " unexpected error on SMB posix open"
352 ", disabling posix open support."
353 " Check if server update available.",
354 tcon->ses->serverName,
355 tcon->ses->serverNOS));
356 tcon->broken_posix_open = true;
347 } else if ((rc != -EIO) && (rc != -EREMOTE) && 357 } else if ((rc != -EIO) && (rc != -EREMOTE) &&
348 (rc != -EOPNOTSUPP)) /* path not found or net err */ 358 (rc != -EOPNOTSUPP)) /* path not found or net err */
349 goto out; 359 goto out;
350 /* fallthrough to retry open the old way on operation 360 /* else fallthrough to retry open the old way on network i/o
351 not supported or DFS errors */ 361 or DFS errors */
352 } 362 }
353 363
354 desiredAccess = cifs_convert_flags(file->f_flags); 364 desiredAccess = cifs_convert_flags(file->f_flags);