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 | ||