diff options
author | Steve French <sfrench@us.ibm.com> | 2009-03-04 14:54:08 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2009-03-11 21:36:21 -0400 |
commit | 64cc2c63694a03393985ffc8b178e72f52dd8a06 (patch) | |
tree | 819161cd3f6b4268b5ff21dfb0c427496134fef5 /fs/cifs/file.c | |
parent | 276a74a4835ad86d6da42f3a084b060afc5656e8 (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.c | 16 |
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); |