Skip to content

Commit f16d59b

Browse files
Christoph HellwigSteve French
authored andcommitted
cifs: use cifs_dirent to replace cifs_get_name_from_search_buf
This allows us to parse the on the wire structures only once in cifs_filldir. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent cda0ec6 commit f16d59b

File tree

1 file changed

+23
-86
lines changed

1 file changed

+23
-86
lines changed

fs/cifs/readdir.c

Lines changed: 23 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -656,82 +656,6 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
656656
return rc;
657657
}
658658

659-
/* inode num, inode type and filename returned */
660-
static int cifs_get_name_from_search_buf(struct qstr *pqst,
661-
char *current_entry, __u16 level, unsigned int unicode,
662-
struct cifs_sb_info *cifs_sb, unsigned int max_len, __u64 *pinum)
663-
{
664-
int rc = 0;
665-
unsigned int len = 0;
666-
char *filename;
667-
struct nls_table *nlt = cifs_sb->local_nls;
668-
669-
*pinum = 0;
670-
671-
if (level == SMB_FIND_FILE_UNIX) {
672-
FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
673-
674-
filename = &pFindData->FileName[0];
675-
if (unicode) {
676-
len = cifs_unicode_bytelen(filename);
677-
} else {
678-
/* BB should we make this strnlen of PATH_MAX? */
679-
len = strnlen(filename, PATH_MAX);
680-
}
681-
682-
*pinum = le64_to_cpu(pFindData->basic.UniqueId);
683-
} else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
684-
FILE_DIRECTORY_INFO *pFindData =
685-
(FILE_DIRECTORY_INFO *)current_entry;
686-
filename = &pFindData->FileName[0];
687-
len = le32_to_cpu(pFindData->FileNameLength);
688-
} else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
689-
FILE_FULL_DIRECTORY_INFO *pFindData =
690-
(FILE_FULL_DIRECTORY_INFO *)current_entry;
691-
filename = &pFindData->FileName[0];
692-
len = le32_to_cpu(pFindData->FileNameLength);
693-
} else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
694-
SEARCH_ID_FULL_DIR_INFO *pFindData =
695-
(SEARCH_ID_FULL_DIR_INFO *)current_entry;
696-
filename = &pFindData->FileName[0];
697-
len = le32_to_cpu(pFindData->FileNameLength);
698-
*pinum = le64_to_cpu(pFindData->UniqueId);
699-
} else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
700-
FILE_BOTH_DIRECTORY_INFO *pFindData =
701-
(FILE_BOTH_DIRECTORY_INFO *)current_entry;
702-
filename = &pFindData->FileName[0];
703-
len = le32_to_cpu(pFindData->FileNameLength);
704-
} else if (level == SMB_FIND_FILE_INFO_STANDARD) {
705-
FIND_FILE_STANDARD_INFO *pFindData =
706-
(FIND_FILE_STANDARD_INFO *)current_entry;
707-
filename = &pFindData->FileName[0];
708-
/* one byte length, no name conversion */
709-
len = (unsigned int)pFindData->FileNameLength;
710-
} else {
711-
cFYI(1, "Unknown findfirst level %d", level);
712-
return -EINVAL;
713-
}
714-
715-
if (len > max_len) {
716-
cERROR(1, "bad search response length %d past smb end", len);
717-
return -EINVAL;
718-
}
719-
720-
if (unicode) {
721-
pqst->len = cifs_from_ucs2((char *) pqst->name,
722-
(__le16 *) filename,
723-
UNICODE_NAME_MAX,
724-
min(len, max_len), nlt,
725-
cifs_sb->mnt_cifs_flags &
726-
CIFS_MOUNT_MAP_SPECIAL_CHR);
727-
pqst->len -= nls_nullsize(nlt);
728-
} else {
729-
pqst->name = filename;
730-
pqst->len = len;
731-
}
732-
return rc;
733-
}
734-
735659
static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
736660
void *dirent, char *scratch_buf, unsigned int max_len)
737661
{
@@ -743,25 +667,38 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
743667
struct dentry *dentry;
744668
struct qstr name;
745669
int rc = 0;
746-
u64 inum;
747670
ino_t ino;
748671

749672
rc = cifs_fill_dirent(&de, find_entry, file_info->srch_inf.info_level,
750673
file_info->srch_inf.unicode);
751674
if (rc)
752675
return rc;
753676

677+
if (de.namelen > max_len) {
678+
cERROR(1, "bad search response length %zd past smb end",
679+
de.namelen);
680+
return -EINVAL;
681+
}
682+
754683
/* skip . and .. since we added them first */
755684
if (cifs_entry_is_dot(&de, file_info->srch_inf.unicode))
756685
return 0;
757686

758-
name.name = scratch_buf;
759-
rc = cifs_get_name_from_search_buf(&name, find_entry,
760-
file_info->srch_inf.info_level,
761-
file_info->srch_inf.unicode,
762-
cifs_sb, max_len, &inum);
763-
if (rc)
764-
return rc;
687+
if (file_info->srch_inf.unicode) {
688+
struct nls_table *nlt = cifs_sb->local_nls;
689+
690+
name.name = scratch_buf;
691+
name.len =
692+
cifs_from_ucs2((char *)name.name, (__le16 *)de.name,
693+
UNICODE_NAME_MAX,
694+
min(de.namelen, (size_t)max_len), nlt,
695+
cifs_sb->mnt_cifs_flags &
696+
CIFS_MOUNT_MAP_SPECIAL_CHR);
697+
name.len -= nls_nullsize(nlt);
698+
} else {
699+
name.name = de.name;
700+
name.len = de.namelen;
701+
}
765702

766703
switch (file_info->srch_inf.info_level) {
767704
case SMB_FIND_FILE_UNIX:
@@ -781,8 +718,8 @@ static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
781718
break;
782719
}
783720

784-
if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
785-
fattr.cf_uniqueid = inum;
721+
if (de.ino && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
722+
fattr.cf_uniqueid = de.ino;
786723
} else {
787724
fattr.cf_uniqueid = iunique(sb, ROOT_I);
788725
cifs_autodisable_serverino(cifs_sb);

0 commit comments

Comments
 (0)