mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
1e77a8c204
commit
3b7960cace
|
@ -784,43 +784,50 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
|
||||||
} else if ((rc == -EACCES) && backup_cred(cifs_sb) &&
|
} else if ((rc == -EACCES) && backup_cred(cifs_sb) &&
|
||||||
(strcmp(server->vals->version_string, SMB1_VERSION_STRING)
|
(strcmp(server->vals->version_string, SMB1_VERSION_STRING)
|
||||||
== 0)) {
|
== 0)) {
|
||||||
/*
|
/*
|
||||||
* For SMB2 and later the backup intent flag is already
|
* For SMB2 and later the backup intent flag is already
|
||||||
* sent if needed on open and there is no path based
|
* sent if needed on open and there is no path based
|
||||||
* FindFirst operation to use to retry with
|
* FindFirst operation to use to retry with
|
||||||
*/
|
*/
|
||||||
|
|
||||||
srchinf = kzalloc(sizeof(struct cifs_search_info),
|
srchinf = kzalloc(sizeof(struct cifs_search_info),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (srchinf == NULL) {
|
if (srchinf == NULL) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto cgii_exit;
|
goto cgii_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
srchinf->endOfSearch = false;
|
srchinf->endOfSearch = false;
|
||||||
|
if (tcon->unix_ext)
|
||||||
|
srchinf->info_level = SMB_FIND_FILE_UNIX;
|
||||||
|
else if ((tcon->ses->capabilities &
|
||||||
|
tcon->ses->server->vals->cap_nt_find) == 0)
|
||||||
|
srchinf->info_level = SMB_FIND_FILE_INFO_STANDARD;
|
||||||
|
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
|
||||||
srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
|
srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
|
||||||
|
else /* no srvino useful for fallback to some netapp */
|
||||||
|
srchinf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
|
||||||
|
|
||||||
srchflgs = CIFS_SEARCH_CLOSE_ALWAYS |
|
srchflgs = CIFS_SEARCH_CLOSE_ALWAYS |
|
||||||
CIFS_SEARCH_CLOSE_AT_END |
|
CIFS_SEARCH_CLOSE_AT_END |
|
||||||
CIFS_SEARCH_BACKUP_SEARCH;
|
CIFS_SEARCH_BACKUP_SEARCH;
|
||||||
|
|
||||||
rc = CIFSFindFirst(xid, tcon, full_path,
|
rc = CIFSFindFirst(xid, tcon, full_path,
|
||||||
cifs_sb, NULL, srchflgs, srchinf, false);
|
cifs_sb, NULL, srchflgs, srchinf, false);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
data =
|
data = (FILE_ALL_INFO *)srchinf->srch_entries_start;
|
||||||
(FILE_ALL_INFO *)srchinf->srch_entries_start;
|
|
||||||
|
|
||||||
cifs_dir_info_to_fattr(&fattr,
|
cifs_dir_info_to_fattr(&fattr,
|
||||||
(FILE_DIRECTORY_INFO *)data, cifs_sb);
|
(FILE_DIRECTORY_INFO *)data, cifs_sb);
|
||||||
fattr.cf_uniqueid = le64_to_cpu(
|
fattr.cf_uniqueid = le64_to_cpu(
|
||||||
((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId);
|
((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId);
|
||||||
validinum = true;
|
validinum = true;
|
||||||
|
|
||||||
cifs_buf_release(srchinf->ntwrk_buf_start);
|
cifs_buf_release(srchinf->ntwrk_buf_start);
|
||||||
}
|
}
|
||||||
kfree(srchinf);
|
kfree(srchinf);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto cgii_exit;
|
goto cgii_exit;
|
||||||
} else
|
} else
|
||||||
goto cgii_exit;
|
goto cgii_exit;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue