aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <stfrench@microsoft.com>2018-10-19 02:58:22 -0400
committerSteve French <stfrench@microsoft.com>2018-10-23 22:16:05 -0400
commit3b7960caceafdfc2cdfe2850487f8d091eb41144 (patch)
treea84583cf449cca8d5db29d3bf0c9be31b7996d68
parent1e77a8c204c9d1b655c61751b8ad0fde22421dbb (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.c67
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