aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r--fs/cifs/dir.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 11431ed72a7f..3758965d73d5 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -225,6 +225,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
225 if (!(oflags & FMODE_READ)) 225 if (!(oflags & FMODE_READ))
226 write_only = true; 226 write_only = true;
227 227
228 mode &= ~current_umask();
228 rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, 229 rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode,
229 pnetfid, presp_data, &oplock, full_path, 230 pnetfid, presp_data, &oplock, full_path,
230 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 231 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
@@ -310,7 +311,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
310 return -ENOMEM; 311 return -ENOMEM;
311 } 312 }
312 313
313 mode &= ~current_umask();
314 if (oplockEnabled) 314 if (oplockEnabled)
315 oplock = REQ_OPLOCK; 315 oplock = REQ_OPLOCK;
316 316
@@ -336,7 +336,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
336 else /* success, no need to query */ 336 else /* success, no need to query */
337 goto cifs_create_set_dentry; 337 goto cifs_create_set_dentry;
338 } else if ((rc != -EIO) && (rc != -EREMOTE) && 338 } else if ((rc != -EIO) && (rc != -EREMOTE) &&
339 (rc != -EOPNOTSUPP)) /* path not found or net err */ 339 (rc != -EOPNOTSUPP) && (rc != -EINVAL))
340 goto cifs_create_out; 340 goto cifs_create_out;
341 /* else fallthrough to retry, using older open call, this is 341 /* else fallthrough to retry, using older open call, this is
342 case where server does not support this SMB level, and 342 case where server does not support this SMB level, and
@@ -609,7 +609,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
609 int xid; 609 int xid;
610 int rc = 0; /* to get around spurious gcc warning, set to zero here */ 610 int rc = 0; /* to get around spurious gcc warning, set to zero here */
611 int oplock = 0; 611 int oplock = 0;
612 int mode;
613 __u16 fileHandle = 0; 612 __u16 fileHandle = 0;
614 bool posix_open = false; 613 bool posix_open = false;
615 struct cifs_sb_info *cifs_sb; 614 struct cifs_sb_info *cifs_sb;
@@ -658,30 +657,36 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
658 } 657 }
659 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));
660 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 */
661 if (pTcon->unix_ext) { 670 if (pTcon->unix_ext) {
662 if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && 671 if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
663 (nd->flags & LOOKUP_OPEN)) { 672 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
664 if (!((nd->intent.open.flags & O_CREAT) && 673 (nd->intent.open.flags & O_CREAT)) {
665 (nd->intent.open.flags & O_EXCL))) { 674 rc = cifs_posix_open(full_path, &newInode,
666 mode = nd->intent.open.create_mode & 675 parent_dir_inode->i_sb,
667 ~current_umask(); 676 nd->intent.open.create_mode,
668 rc = cifs_posix_open(full_path, &newInode,
669 parent_dir_inode->i_sb, mode,
670 nd->intent.open.flags, &oplock, 677 nd->intent.open.flags, &oplock,
671 &fileHandle, xid); 678 &fileHandle, xid);
672 /* 679 /*
673 * This code works around a bug in 680 * The check below works around a bug in POSIX
674 * samba posix open in samba versions 3.3.1 681 * open in samba versions 3.3.1 and earlier where
675 * and earlier where create works 682 * open could incorrectly fail with invalid parameter.
676 * but open fails with invalid parameter. 683 * If either that or op not supported returned, follow
677 * If either of these error codes are 684 * the normal lookup.
678 * returned, follow the normal lookup. 685 */
679 * Otherwise, the error during posix open 686 if ((rc == 0) || (rc == -ENOENT))
680 * is handled. 687 posix_open = true;
681 */ 688 else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
682 if ((rc != -EINVAL) && (rc != -EOPNOTSUPP)) 689 pTcon->broken_posix_open = true;
683 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,