]>
Commit | Line | Data |
---|---|---|
39f3dcdc SLM |
1 | From eed3d69b5cc024a6193dbd9b94a27d8b8356d3d9 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 | |
5 | ||
6 | [ Upstream commit 3b7960caceafdfc2cdfe2850487f8d091eb41144 ] | |
7 | ||
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). | |
14 | ||
15 | (Also fixes some indentation) | |
16 | ||
17 | See kernel bugzilla 201435 | |
18 | ||
19 | Signed-off-by: Steve French <stfrench@microsoft.com> | |
20 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
21 | --- | |
22 | fs/cifs/inode.c | 67 +++++++++++++++++++++++++++---------------------- | |
23 | 1 file changed, 37 insertions(+), 30 deletions(-) | |
24 | ||
25 | diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c | |
26 | index a90a637ae79a..6fd4a6a75234 100644 | |
27 | --- a/fs/cifs/inode.c | |
28 | +++ b/fs/cifs/inode.c | |
29 | @@ -779,43 +779,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) | |
32 | == 0)) { | |
33 | - /* | |
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 | |
37 | - */ | |
38 | + /* | |
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 | |
42 | + */ | |
43 | ||
44 | - srchinf = kzalloc(sizeof(struct cifs_search_info), | |
45 | - GFP_KERNEL); | |
46 | - if (srchinf == NULL) { | |
47 | - rc = -ENOMEM; | |
48 | - goto cgii_exit; | |
49 | - } | |
50 | + srchinf = kzalloc(sizeof(struct cifs_search_info), | |
51 | + GFP_KERNEL); | |
52 | + if (srchinf == NULL) { | |
53 | + rc = -ENOMEM; | |
54 | + goto cgii_exit; | |
55 | + } | |
56 | ||
57 | - srchinf->endOfSearch = false; | |
58 | + srchinf->endOfSearch = false; | |
59 | + if (tcon->unix_ext) | |
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; | |
68 | ||
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; | |
75 | ||
76 | - rc = CIFSFindFirst(xid, tcon, full_path, | |
77 | - cifs_sb, NULL, srchflgs, srchinf, false); | |
78 | - if (!rc) { | |
79 | - data = | |
80 | - (FILE_ALL_INFO *)srchinf->srch_entries_start; | |
81 | + rc = CIFSFindFirst(xid, tcon, full_path, | |
82 | + cifs_sb, NULL, srchflgs, srchinf, false); | |
83 | + if (!rc) { | |
84 | + data = (FILE_ALL_INFO *)srchinf->srch_entries_start; | |
85 | ||
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); | |
90 | - validinum = true; | |
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); | |
95 | + validinum = true; | |
96 | ||
97 | - cifs_buf_release(srchinf->ntwrk_buf_start); | |
98 | - } | |
99 | - kfree(srchinf); | |
100 | - if (rc) | |
101 | - goto cgii_exit; | |
102 | + cifs_buf_release(srchinf->ntwrk_buf_start); | |
103 | + } | |
104 | + kfree(srchinf); | |
105 | + if (rc) | |
106 | + goto cgii_exit; | |
107 | } else | |
108 | goto cgii_exit; | |
109 | ||
110 | -- | |
111 | 2.19.1 | |
112 |