Skip to content

Commit 1d41cd1

Browse files
Steve Frenchgregkh
authored andcommitted
cifs: fallback to older infolevels on findfirst queryinfo retry
[ Upstream commit 3b7960c ] 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 <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 82017e2 commit 1d41cd1

File tree

1 file changed

+37
-30
lines changed

1 file changed

+37
-30
lines changed

fs/cifs/inode.c

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -779,43 +779,50 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
779779
} else if ((rc == -EACCES) && backup_cred(cifs_sb) &&
780780
(strcmp(server->vals->version_string, SMB1_VERSION_STRING)
781781
== 0)) {
782-
/*
783-
* For SMB2 and later the backup intent flag is already
784-
* sent if needed on open and there is no path based
785-
* FindFirst operation to use to retry with
786-
*/
782+
/*
783+
* For SMB2 and later the backup intent flag is already
784+
* sent if needed on open and there is no path based
785+
* FindFirst operation to use to retry with
786+
*/
787787

788-
srchinf = kzalloc(sizeof(struct cifs_search_info),
789-
GFP_KERNEL);
790-
if (srchinf == NULL) {
791-
rc = -ENOMEM;
792-
goto cgii_exit;
793-
}
788+
srchinf = kzalloc(sizeof(struct cifs_search_info),
789+
GFP_KERNEL);
790+
if (srchinf == NULL) {
791+
rc = -ENOMEM;
792+
goto cgii_exit;
793+
}
794794

795-
srchinf->endOfSearch = false;
795+
srchinf->endOfSearch = false;
796+
if (tcon->unix_ext)
797+
srchinf->info_level = SMB_FIND_FILE_UNIX;
798+
else if ((tcon->ses->capabilities &
799+
tcon->ses->server->vals->cap_nt_find) == 0)
800+
srchinf->info_level = SMB_FIND_FILE_INFO_STANDARD;
801+
else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
796802
srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
803+
else /* no srvino useful for fallback to some netapp */
804+
srchinf->info_level = SMB_FIND_FILE_DIRECTORY_INFO;
797805

798-
srchflgs = CIFS_SEARCH_CLOSE_ALWAYS |
799-
CIFS_SEARCH_CLOSE_AT_END |
800-
CIFS_SEARCH_BACKUP_SEARCH;
806+
srchflgs = CIFS_SEARCH_CLOSE_ALWAYS |
807+
CIFS_SEARCH_CLOSE_AT_END |
808+
CIFS_SEARCH_BACKUP_SEARCH;
801809

802-
rc = CIFSFindFirst(xid, tcon, full_path,
803-
cifs_sb, NULL, srchflgs, srchinf, false);
804-
if (!rc) {
805-
data =
806-
(FILE_ALL_INFO *)srchinf->srch_entries_start;
810+
rc = CIFSFindFirst(xid, tcon, full_path,
811+
cifs_sb, NULL, srchflgs, srchinf, false);
812+
if (!rc) {
813+
data = (FILE_ALL_INFO *)srchinf->srch_entries_start;
807814

808-
cifs_dir_info_to_fattr(&fattr,
809-
(FILE_DIRECTORY_INFO *)data, cifs_sb);
810-
fattr.cf_uniqueid = le64_to_cpu(
811-
((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId);
812-
validinum = true;
815+
cifs_dir_info_to_fattr(&fattr,
816+
(FILE_DIRECTORY_INFO *)data, cifs_sb);
817+
fattr.cf_uniqueid = le64_to_cpu(
818+
((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId);
819+
validinum = true;
813820

814-
cifs_buf_release(srchinf->ntwrk_buf_start);
815-
}
816-
kfree(srchinf);
817-
if (rc)
818-
goto cgii_exit;
821+
cifs_buf_release(srchinf->ntwrk_buf_start);
822+
}
823+
kfree(srchinf);
824+
if (rc)
825+
goto cgii_exit;
819826
} else
820827
goto cgii_exit;
821828

0 commit comments

Comments
 (0)