diff options
| author | Steve French <stfrench@microsoft.com> | 2018-10-19 02:58:22 -0400 |
|---|---|---|
| committer | Steve French <stfrench@microsoft.com> | 2018-10-23 22:16:05 -0400 |
| commit | 3b7960caceafdfc2cdfe2850487f8d091eb41144 (patch) | |
| tree | a84583cf449cca8d5db29d3bf0c9be31b7996d68 | |
| parent | 1e77a8c204c9d1b655c61751b8ad0fde22421dbb (diff) | |
cifs: fallback to older infolevels on findfirst queryinfo retry
In cases where queryinfo fails, we have cases in cifs (vers=1.0)
where with backupuid mounts we retry the query info with findfirst.
This doesn't work to some NetApp servers which don't support
WindowsXP (and later) infolevel 261 (SMB_FIND_FILE_ID_FULL_DIR_INFO)
so in this case use other info levels (in this case it will usually
be level 257, SMB_FIND_FILE_DIRECTORY_INFO).
(Also fixes some indentation)
See kernel bugzilla 201435
Signed-off-by: Steve French <stfrench@microsoft.com>
| -rw-r--r-- | fs/cifs/inode.c | 67 |
1 files changed, 37 insertions, 30 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 7483c09317b9..1023d78673fb 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -784,43 +784,50 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, | |||
| 784 | } else if ((rc == -EACCES) && backup_cred(cifs_sb) && | 784 | } else if ((rc == -EACCES) && backup_cred(cifs_sb) && |
| 785 | (strcmp(server->vals->version_string, SMB1_VERSION_STRING) | 785 | (strcmp(server->vals->version_string, SMB1_VERSION_STRING) |
| 786 | == 0)) { | 786 | == 0)) { |
| 787 | /* | 787 | /* |
| 788 | * For SMB2 and later the backup intent flag is already | 788 | * For SMB2 and later the backup intent flag is already |
| 789 | * sent if needed on open and there is no path based | 789 | * sent if needed on open and there is no path based |
| 790 | * FindFirst operation to use to retry with | 790 | * FindFirst operation to use to retry with |
| 791 | */ | 791 | */ |
| 792 | 792 | ||
| 793 | srchinf = kzalloc(sizeof(struct cifs_search_info), | 793 | srchinf = kzalloc(sizeof(struct cifs_search_info), |
| 794 | GFP_KERNEL); | 794 | GFP_KERNEL); |
| 795 | if (srchinf == NULL) { | 795 | if (srchinf == NULL) { |
| 796 | rc = -ENOMEM; | 796 | rc = -ENOMEM; |
| 797 | goto cgii_exit; | 797 | goto cgii_exit; |
| 798 | } | 798 | } |
| 799 | 799 | ||
| 800 | srchinf->endOfSearch = false; | 800 | srchinf->endOfSearch = false; |
| 801 | if (tcon->unix_ext) | ||
| 802 | srchinf->info_level = SMB_FIND_FILE_UNIX; | ||
| 803 | else if ((tcon->ses->capabilities & | ||
| 804 | tcon->ses->server->vals->cap_nt_find) == 0) | ||
| 805 | srchinf->info_level = SMB_FIND_FILE_INFO_STANDARD; | ||
| 806 | else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) | ||
| 801 | srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; | 807 | srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; |
| 808 | else /* no srvino useful for fallback to some netapp */ | ||
| 809 | srchinf->info_level = SMB_FIND_FILE_DIRECTORY_INFO; | ||
| 802 | 810 | ||
| 803 | srchflgs = CIFS_SEARCH_CLOSE_ALWAYS | | 811 | srchflgs = CIFS_SEARCH_CLOSE_ALWAYS | |
| 804 | CIFS_SEARCH_CLOSE_AT_END | | 812 | CIFS_SEARCH_CLOSE_AT_END | |
| 805 | CIFS_SEARCH_BACKUP_SEARCH; | 813 | CIFS_SEARCH_BACKUP_SEARCH; |
| 806 | 814 | ||
| 807 | rc = CIFSFindFirst(xid, tcon, full_path, | 815 | rc = CIFSFindFirst(xid, tcon, full_path, |
| 808 | cifs_sb, NULL, srchflgs, srchinf, false); | 816 | cifs_sb, NULL, srchflgs, srchinf, false); |
| 809 | if (!rc) { | 817 | if (!rc) { |
| 810 | data = | 818 | data = (FILE_ALL_INFO *)srchinf->srch_entries_start; |
| 811 | (FILE_ALL_INFO *)srchinf->srch_entries_start; | ||
| 812 | 819 | ||
| 813 | cifs_dir_info_to_fattr(&fattr, | 820 | cifs_dir_info_to_fattr(&fattr, |
| 814 | (FILE_DIRECTORY_INFO *)data, cifs_sb); | 821 | (FILE_DIRECTORY_INFO *)data, cifs_sb); |
| 815 | fattr.cf_uniqueid = le64_to_cpu( | 822 | fattr.cf_uniqueid = le64_to_cpu( |
| 816 | ((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId); | 823 | ((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId); |
| 817 | validinum = true; | 824 | validinum = true; |
| 818 | 825 | ||
| 819 | cifs_buf_release(srchinf->ntwrk_buf_start); | 826 | cifs_buf_release(srchinf->ntwrk_buf_start); |
| 820 | } | 827 | } |
| 821 | kfree(srchinf); | 828 | kfree(srchinf); |
| 822 | if (rc) | 829 | if (rc) |
| 823 | goto cgii_exit; | 830 | goto cgii_exit; |
| 824 | } else | 831 | } else |
| 825 | goto cgii_exit; | 832 | goto cgii_exit; |
| 826 | 833 | ||
