aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2009-05-23 14:57:25 -0400
committerSteve French <sfrench@us.ibm.com>2009-05-23 14:57:25 -0400
commit8db14ca12569fe885694bd3d5ff84c2d973d3cb0 (patch)
treec1648afbd9c6e93b6b48f230c5c7dbb3d0184a2b /fs/cifs/dir.c
parenta15ae93ff7c710191362978453f306943808298d (diff)
[CIFS] Avoid open on possible directories since Samba now rejects them
Small change (mostly formatting) to limit lookup based open calls to file create only. After discussion yesteday on samba-technical about the posix lookup 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). 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), this change avoids the posix open code on lookup open (just issues posix open on creates). This gets the semantic benefits we want (atomicity, posix byte range locks, improved write semantics on newly created files) and file create still is fast, and we avoid the problem that Jeff noticed yesterday 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). I confirmed this approach with jra yesterday and with Shirish today. Posix open is only called (at lookup time) for file create now. For opens (rather than creates), because we do not know if it is a file or directory yet, and current Samba no longer allows us to do posix open on dirs, we could end up wasting an open call on what turns out to be a dir. For file opens, we wait to call posix open till cifs_open. It could be added here (lookup) in the future but the performance tradeoff of the extra network request when EISDIR or EACCES is returned would have to be weighed against the 50% reduction in network traffic in the other paths. Reviewed-by: Shirish Pargaonkar <shirishp@us.ibm.com> Tested-by: Jeff Layton <jlayton@redhat.com> CC: Jeremy Allison <jra@samba.org> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r--fs/cifs/dir.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index f49d684edd96..3758965d73d5 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -657,31 +657,36 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
657 } 657 }
658 cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode)); 658 cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode));
659 659
660 /* Posix open is only called (at lookup time) for file create now.
661 * For opens (rather than creates), because we do not know if it
662 * is a file or directory yet, and current Samba no longer allows
663 * us to do posix open on dirs, we could end up wasting an open call
664 * on what turns out to be a dir. For file opens, we wait to call posix
665 * open till cifs_open. It could be added here (lookup) in the future
666 * but the performance tradeoff of the extra network request when EISDIR
667 * or EACCES is returned would have to be weighed against the 50%
668 * reduction in network traffic in the other paths.
669 */
660 if (pTcon->unix_ext) { 670 if (pTcon->unix_ext) {
661 if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && 671 if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
662 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open) { 672 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
663 if (!((nd->intent.open.flags & O_CREAT) && 673 (nd->intent.open.flags & O_CREAT)) {
664 (nd->intent.open.flags & O_EXCL))) { 674 rc = cifs_posix_open(full_path, &newInode,
665 rc = cifs_posix_open(full_path, &newInode,
666 parent_dir_inode->i_sb, 675 parent_dir_inode->i_sb,
667 nd->intent.open.create_mode, 676 nd->intent.open.create_mode,
668 nd->intent.open.flags, &oplock, 677 nd->intent.open.flags, &oplock,
669 &fileHandle, xid); 678 &fileHandle, xid);
670 /* 679 /*
671 * This code works around a bug in 680 * The check below works around a bug in POSIX
672 * samba posix open in samba versions 3.3.1 681 * open in samba versions 3.3.1 and earlier where
673 * and earlier where create works 682 * open could incorrectly fail with invalid parameter.
674 * but open fails with invalid parameter. 683 * If either that or op not supported returned, follow
675 * If either of these error codes are 684 * the normal lookup.
676 * returned, follow the normal lookup. 685 */
677 * Otherwise, the error during posix open 686 if ((rc == 0) || (rc == -ENOENT))
678 * is handled. 687 posix_open = true;
679 */ 688 else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
680 if ((rc != -EINVAL) && (rc != -EOPNOTSUPP)) 689 pTcon->broken_posix_open = true;
681 posix_open = true;
682 else
683 pTcon->broken_posix_open = true;
684 }
685 } 690 }
686 if (!posix_open) 691 if (!posix_open)
687 rc = cifs_get_inode_info_unix(&newInode, full_path, 692 rc = cifs_get_inode_info_unix(&newInode, full_path,