diff mbox

[linux-cifs-client,CIFS] One more posix open patch on the way

Message ID 524f69650905221928he49410ay75000927c73bf93b@mail.gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Steve French May 23, 2009, 2:28 a.m. UTC
One small additional fix to posix open is being reviewed to address
something Jeff and JRA noticed this morning.

After discussion today on samba-technical about the posix lookup open
regression,  and looking at a problem with cifs posix open to one
particular Samba version, Jeff and JRA realized that Samba server's
behavior changed in this area (posix open behavior on files vs.
directories) too.   To make this behavior consistent, JRA just made a
fix to Samba server to alter how it handles open of directories (now
returning the equivalent of EISDIR instead of success). Since we don't
know at lookup time whether the inode is a directory or file (and thus
whether posix open will succeed with most current Samba server), I am
testing a change which avoids the posix open code on lookup open (just
issues posix open on creates).    This gets the semantic benefits we
want (posix byte range locks, improved write semantics etc. on newly
created files) and file create still is fast, and we avoid the problem
that Jeff noticed this morning with "openat" (and some open directory
calls) of non-cached directories to one version of Samba server, and
will work with future Samba versions (which include the fix jra just
pushed into Samba server).

The small fix attached (or something like it), is a mustfix before
2.6.30 goes out, but want to give Shirish, and Jeff time to look at
it.  The main part (other than a trivial rc mapping change) is this
change to cifs_lookup

 					nd->intent.open.create_mode,
diff mbox

Patch

diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index f49d684..c306d3f 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -660,8 +660,16 @@  cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
 	if (pTcon->unix_ext) {
 		if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
 		     (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open) {
-			if (!((nd->intent.open.flags & O_CREAT) &&
-					(nd->intent.open.flags & O_EXCL))) {
+			if (nd->intent.open.flags & O_CREAT) {
+				/* POSIX open here is only called for file
+				   create. It does not help much for file opens
+				   because we do not know if it is a file
+				   or directory, and current Samba no
+				   longer allows us to do posix open on dirs,
+				   so we could end up wasting an open
+				   call on what turns out to be a dir. 
+				   For file opens, we call posix open
+				   in cifs_open */
 				rc = cifs_posix_open(full_path, &newInode,
 					parent_dir_inode->i_sb,
 					nd->intent.open.create_mode,
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index e2fe998..f465aaf 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -79,6 +79,7 @@  static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
 	{ErrQuota, -EDQUOT},
 	{ErrNotALink, -ENOLINK},
 	{ERRnetlogonNotStarted, -ENOPROTOOPT},
+	{ERRisdir, -EISDIR},
 	{ERRsymlink, -EOPNOTSUPP},
 	{ErrTooManyLinks, -EMLINK},
 	{0, 0}
@@ -368,7 +369,7 @@  static const struct {
 	ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STARTED}, {
 	ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STOPPED}, {
 	ERRHRD, ERRgeneral, NT_STATUS_COULD_NOT_INTERPRET}, {
-	ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, {
+	ERRDOS, ERRisdir, NT_STATUS_FILE_IS_A_DIRECTORY}, {
 	ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED}, {
 	ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, {
 	ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, {
diff --git a/fs/cifs/smberr.h b/fs/cifs/smberr.h
index c5084d2..5481525 100644
--- a/fs/cifs/smberr.h
+++ b/fs/cifs/smberr.h
@@ -110,6 +110,7 @@ 
 
 /* Below errors are used internally (do not come over the wire) for passthrough
    from STATUS codes to POSIX only  */
+#define ERRisdir		0xFFFC
 #define ERRsymlink              0xFFFD
 #define ErrTooManyLinks         0xFFFE