mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 06:04:23 +08:00
[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>
This commit is contained in:
parent
276a74a483
commit
64cc2c6369
@ -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
|
server disk (not just write it over the network). Add new mount
|
||||||
parameter to allow user to disable sending the (slow) SMB flush on
|
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).
|
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
|
Version 1.56
|
||||||
------------
|
------------
|
||||||
|
@ -299,6 +299,7 @@ struct cifsTconInfo {
|
|||||||
bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol
|
bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol
|
||||||
for this mount even if server would support */
|
for this mount even if server would support */
|
||||||
bool local_lease:1; /* check leases (only) on local system not remote */
|
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 */
|
bool need_reconnect:1; /* connection reset, tid now invalid */
|
||||||
/* BB add field for back pointer to sb struct(s)? */
|
/* BB add field for back pointer to sb struct(s)? */
|
||||||
};
|
};
|
||||||
|
@ -328,7 +328,8 @@ int cifs_open(struct inode *inode, struct file *file)
|
|||||||
else
|
else
|
||||||
oplock = 0;
|
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 &
|
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
|
||||||
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
|
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
|
||||||
int oflags = (int) cifs_posix_convert_flags(file->f_flags);
|
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,
|
cifs_posix_open_inode_helper(inode, file, pCifsInode,
|
||||||
pCifsFile, oplock, netfid);
|
pCifsFile, oplock, netfid);
|
||||||
goto out;
|
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) &&
|
} else if ((rc != -EIO) && (rc != -EREMOTE) &&
|
||||||
(rc != -EOPNOTSUPP)) /* path not found or net err */
|
(rc != -EOPNOTSUPP)) /* path not found or net err */
|
||||||
goto out;
|
goto out;
|
||||||
/* fallthrough to retry open the old way on operation
|
/* else fallthrough to retry open the old way on network i/o
|
||||||
not supported or DFS errors */
|
or DFS errors */
|
||||||
}
|
}
|
||||||
|
|
||||||
desiredAccess = cifs_convert_flags(file->f_flags);
|
desiredAccess = cifs_convert_flags(file->f_flags);
|
||||||
|
Loading…
Reference in New Issue
Block a user