diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/dir.c | 43 |
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, |