1 From 59a58697c297918bace9fdd1a25cd211fabf1fa1 Mon Sep 17 00:00:00 2001
2 From: Steve French <stfrench@microsoft.com>
3 Date: Fri, 19 Oct 2018 01:58:22 -0500
4 Subject: cifs: fallback to older infolevels on findfirst queryinfo retry
6 [ Upstream commit 3b7960caceafdfc2cdfe2850487f8d091eb41144 ]
8 In cases where queryinfo fails, we have cases in cifs (vers=1.0)
9 where with backupuid mounts we retry the query info with findfirst.
10 This doesn't work to some NetApp servers which don't support
11 WindowsXP (and later) infolevel 261 (SMB_FIND_FILE_ID_FULL_DIR_INFO)
12 so in this case use other info levels (in this case it will usually
13 be level 257, SMB_FIND_FILE_DIRECTORY_INFO).
15 (Also fixes some indentation)
17 See kernel bugzilla 201435
19 Signed-off-by: Steve French <stfrench@microsoft.com>
20 Signed-off-by: Sasha Levin <sashal@kernel.org>
22 fs/cifs/inode.c | 67 +++++++++++++++++++++++++++----------------------
23 1 file changed, 37 insertions(+), 30 deletions(-)
25 diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
26 index 57c938ffeb6e..a8a2fc9ae056 100644
29 @@ -771,43 +771,50 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
30 } else if ((rc == -EACCES) && backup_cred(cifs_sb) &&
31 (strcmp(server->vals->version_string, SMB1_VERSION_STRING)
34 - * For SMB2 and later the backup intent flag is already
35 - * sent if needed on open and there is no path based
36 - * FindFirst operation to use to retry with
39 + * For SMB2 and later the backup intent flag is already
40 + * sent if needed on open and there is no path based
41 + * FindFirst operation to use to retry with
44 - srchinf = kzalloc(sizeof(struct cifs_search_info),
46 - if (srchinf == NULL) {
50 + srchinf = kzalloc(sizeof(struct cifs_search_info),
52 + if (srchinf == NULL) {
57 - srchinf->endOfSearch = false;
58 + srchinf->endOfSearch = false;
60 + srchinf->info_level = SMB_FIND_FILE_UNIX;
61 + else if ((tcon->ses->capabilities &
62 + tcon->ses->server->vals->cap_nt_find) == 0)
63 + srchinf->info_level = SMB_FIND_FILE_INFO_STANDARD;
64 + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
65 srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
66 + else /* no srvino useful for fallback to some netapp */
67 + srchinf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
69 - srchflgs = CIFS_SEARCH_CLOSE_ALWAYS |
70 - CIFS_SEARCH_CLOSE_AT_END |
71 - CIFS_SEARCH_BACKUP_SEARCH;
72 + srchflgs = CIFS_SEARCH_CLOSE_ALWAYS |
73 + CIFS_SEARCH_CLOSE_AT_END |
74 + CIFS_SEARCH_BACKUP_SEARCH;
76 - rc = CIFSFindFirst(xid, tcon, full_path,
77 - cifs_sb, NULL, srchflgs, srchinf, false);
80 - (FILE_ALL_INFO *)srchinf->srch_entries_start;
81 + rc = CIFSFindFirst(xid, tcon, full_path,
82 + cifs_sb, NULL, srchflgs, srchinf, false);
84 + data = (FILE_ALL_INFO *)srchinf->srch_entries_start;
86 - cifs_dir_info_to_fattr(&fattr,
87 - (FILE_DIRECTORY_INFO *)data, cifs_sb);
88 - fattr.cf_uniqueid = le64_to_cpu(
89 - ((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId);
91 + cifs_dir_info_to_fattr(&fattr,
92 + (FILE_DIRECTORY_INFO *)data, cifs_sb);
93 + fattr.cf_uniqueid = le64_to_cpu(
94 + ((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId);
97 - cifs_buf_release(srchinf->ntwrk_buf_start);
102 + cifs_buf_release(srchinf->ntwrk_buf_start);