Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64cc2c63 authored by Steve French's avatar Steve French
Browse files

[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: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 276a74a4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
------------
+1 −0
Original line number Diff line number Diff line
@@ -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)? */
};
+13 −3
Original line number Diff line number Diff line
@@ -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);