diff options
| -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, |
