|
@@ -4,6 +4,7 @@
|
|
|
* Directory search handling
|
|
|
*
|
|
|
* Copyright (C) International Business Machines Corp., 2004, 2008
|
|
|
+ * Copyright (C) Red Hat, Inc., 2011
|
|
|
* Author(s): Steve French (sfrench@us.ibm.com)
|
|
|
*
|
|
|
* This library is free software; you can redistribute it and/or modify
|
|
@@ -290,10 +291,10 @@ error_exit:
|
|
|
}
|
|
|
|
|
|
/* return length of unicode string in bytes */
|
|
|
-static int cifs_unicode_bytelen(char *str)
|
|
|
+static int cifs_unicode_bytelen(const char *str)
|
|
|
{
|
|
|
int len;
|
|
|
- __le16 *ustr = (__le16 *)str;
|
|
|
+ const __le16 *ustr = (const __le16 *)str;
|
|
|
|
|
|
for (len = 0; len <= PATH_MAX; len++) {
|
|
|
if (ustr[len] == 0)
|
|
@@ -334,78 +335,128 @@ static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
|
|
|
|
|
|
}
|
|
|
|
|
|
+struct cifs_dirent {
|
|
|
+ const char *name;
|
|
|
+ size_t namelen;
|
|
|
+ u32 resume_key;
|
|
|
+ u64 ino;
|
|
|
+};
|
|
|
+
|
|
|
+static void cifs_fill_dirent_unix(struct cifs_dirent *de,
|
|
|
+ const FILE_UNIX_INFO *info, bool is_unicode)
|
|
|
+{
|
|
|
+ de->name = &info->FileName[0];
|
|
|
+ if (is_unicode)
|
|
|
+ de->namelen = cifs_unicode_bytelen(de->name);
|
|
|
+ else
|
|
|
+ de->namelen = strnlen(de->name, PATH_MAX);
|
|
|
+ de->resume_key = info->ResumeKey;
|
|
|
+ de->ino = le64_to_cpu(info->basic.UniqueId);
|
|
|
+}
|
|
|
+
|
|
|
+static void cifs_fill_dirent_dir(struct cifs_dirent *de,
|
|
|
+ const FILE_DIRECTORY_INFO *info)
|
|
|
+{
|
|
|
+ de->name = &info->FileName[0];
|
|
|
+ de->namelen = le32_to_cpu(info->FileNameLength);
|
|
|
+ de->resume_key = info->FileIndex;
|
|
|
+}
|
|
|
+
|
|
|
+static void cifs_fill_dirent_full(struct cifs_dirent *de,
|
|
|
+ const FILE_FULL_DIRECTORY_INFO *info)
|
|
|
+{
|
|
|
+ de->name = &info->FileName[0];
|
|
|
+ de->namelen = le32_to_cpu(info->FileNameLength);
|
|
|
+ de->resume_key = info->FileIndex;
|
|
|
+}
|
|
|
+
|
|
|
+static void cifs_fill_dirent_search(struct cifs_dirent *de,
|
|
|
+ const SEARCH_ID_FULL_DIR_INFO *info)
|
|
|
+{
|
|
|
+ de->name = &info->FileName[0];
|
|
|
+ de->namelen = le32_to_cpu(info->FileNameLength);
|
|
|
+ de->resume_key = info->FileIndex;
|
|
|
+ de->ino = le64_to_cpu(info->UniqueId);
|
|
|
+}
|
|
|
+
|
|
|
+static void cifs_fill_dirent_both(struct cifs_dirent *de,
|
|
|
+ const FILE_BOTH_DIRECTORY_INFO *info)
|
|
|
+{
|
|
|
+ de->name = &info->FileName[0];
|
|
|
+ de->namelen = le32_to_cpu(info->FileNameLength);
|
|
|
+ de->resume_key = info->FileIndex;
|
|
|
+}
|
|
|
+
|
|
|
+static void cifs_fill_dirent_std(struct cifs_dirent *de,
|
|
|
+ const FIND_FILE_STANDARD_INFO *info)
|
|
|
+{
|
|
|
+ de->name = &info->FileName[0];
|
|
|
+ /* one byte length, no endianess conversion */
|
|
|
+ de->namelen = info->FileNameLength;
|
|
|
+ de->resume_key = info->ResumeKey;
|
|
|
+}
|
|
|
+
|
|
|
+static int cifs_fill_dirent(struct cifs_dirent *de, const void *info,
|
|
|
+ u16 level, bool is_unicode)
|
|
|
+{
|
|
|
+ memset(de, 0, sizeof(*de));
|
|
|
+
|
|
|
+ switch (level) {
|
|
|
+ case SMB_FIND_FILE_UNIX:
|
|
|
+ cifs_fill_dirent_unix(de, info, is_unicode);
|
|
|
+ break;
|
|
|
+ case SMB_FIND_FILE_DIRECTORY_INFO:
|
|
|
+ cifs_fill_dirent_dir(de, info);
|
|
|
+ break;
|
|
|
+ case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
|
|
|
+ cifs_fill_dirent_full(de, info);
|
|
|
+ break;
|
|
|
+ case SMB_FIND_FILE_ID_FULL_DIR_INFO:
|
|
|
+ cifs_fill_dirent_search(de, info);
|
|
|
+ break;
|
|
|
+ case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
|
|
|
+ cifs_fill_dirent_both(de, info);
|
|
|
+ break;
|
|
|
+ case SMB_FIND_FILE_INFO_STANDARD:
|
|
|
+ cifs_fill_dirent_std(de, info);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ cFYI(1, "Unknown findfirst level %d", level);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
#define UNICODE_DOT cpu_to_le16(0x2e)
|
|
|
|
|
|
/* return 0 if no match and 1 for . (current directory) and 2 for .. (parent) */
|
|
|
-static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)
|
|
|
+static int cifs_entry_is_dot(struct cifs_dirent *de, bool is_unicode)
|
|
|
{
|
|
|
int rc = 0;
|
|
|
- char *filename = NULL;
|
|
|
- int len = 0;
|
|
|
-
|
|
|
- if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) {
|
|
|
- FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- if (cfile->srch_inf.unicode) {
|
|
|
- len = cifs_unicode_bytelen(filename);
|
|
|
- } else {
|
|
|
- /* BB should we make this strnlen of PATH_MAX? */
|
|
|
- len = strnlen(filename, 5);
|
|
|
- }
|
|
|
- } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) {
|
|
|
- FILE_DIRECTORY_INFO *pFindData =
|
|
|
- (FILE_DIRECTORY_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- } else if (cfile->srch_inf.info_level ==
|
|
|
- SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
|
|
|
- FILE_FULL_DIRECTORY_INFO *pFindData =
|
|
|
- (FILE_FULL_DIRECTORY_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- } else if (cfile->srch_inf.info_level ==
|
|
|
- SMB_FIND_FILE_ID_FULL_DIR_INFO) {
|
|
|
- SEARCH_ID_FULL_DIR_INFO *pFindData =
|
|
|
- (SEARCH_ID_FULL_DIR_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- } else if (cfile->srch_inf.info_level ==
|
|
|
- SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
|
|
|
- FILE_BOTH_DIRECTORY_INFO *pFindData =
|
|
|
- (FILE_BOTH_DIRECTORY_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- } else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) {
|
|
|
- FIND_FILE_STANDARD_INFO *pFindData =
|
|
|
- (FIND_FILE_STANDARD_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = pFindData->FileNameLength;
|
|
|
- } else {
|
|
|
- cFYI(1, "Unknown findfirst level %d",
|
|
|
- cfile->srch_inf.info_level);
|
|
|
- }
|
|
|
|
|
|
- if (filename) {
|
|
|
- if (cfile->srch_inf.unicode) {
|
|
|
- __le16 *ufilename = (__le16 *)filename;
|
|
|
- if (len == 2) {
|
|
|
- /* check for . */
|
|
|
- if (ufilename[0] == UNICODE_DOT)
|
|
|
- rc = 1;
|
|
|
- } else if (len == 4) {
|
|
|
- /* check for .. */
|
|
|
- if ((ufilename[0] == UNICODE_DOT)
|
|
|
- && (ufilename[1] == UNICODE_DOT))
|
|
|
- rc = 2;
|
|
|
- }
|
|
|
- } else /* ASCII */ {
|
|
|
- if (len == 1) {
|
|
|
- if (filename[0] == '.')
|
|
|
- rc = 1;
|
|
|
- } else if (len == 2) {
|
|
|
- if ((filename[0] == '.') && (filename[1] == '.'))
|
|
|
- rc = 2;
|
|
|
- }
|
|
|
+ if (!de->name)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (is_unicode) {
|
|
|
+ __le16 *ufilename = (__le16 *)de->name;
|
|
|
+ if (de->namelen == 2) {
|
|
|
+ /* check for . */
|
|
|
+ if (ufilename[0] == UNICODE_DOT)
|
|
|
+ rc = 1;
|
|
|
+ } else if (de->namelen == 4) {
|
|
|
+ /* check for .. */
|
|
|
+ if (ufilename[0] == UNICODE_DOT &&
|
|
|
+ ufilename[1] == UNICODE_DOT)
|
|
|
+ rc = 2;
|
|
|
+ }
|
|
|
+ } else /* ASCII */ {
|
|
|
+ if (de->namelen == 1) {
|
|
|
+ if (de->name[0] == '.')
|
|
|
+ rc = 1;
|
|
|
+ } else if (de->namelen == 2) {
|
|
|
+ if (de->name[0] == '.' && de->name[1] == '.')
|
|
|
+ rc = 2;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -427,66 +478,18 @@ static int is_dir_changed(struct file *file)
|
|
|
}
|
|
|
|
|
|
static int cifs_save_resume_key(const char *current_entry,
|
|
|
- struct cifsFileInfo *cifsFile)
|
|
|
+ struct cifsFileInfo *file_info)
|
|
|
{
|
|
|
- int rc = 0;
|
|
|
- unsigned int len = 0;
|
|
|
- __u16 level;
|
|
|
- char *filename;
|
|
|
-
|
|
|
- if ((cifsFile == NULL) || (current_entry == NULL))
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- level = cifsFile->srch_inf.info_level;
|
|
|
-
|
|
|
- if (level == SMB_FIND_FILE_UNIX) {
|
|
|
- FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
|
|
|
+ struct cifs_dirent de;
|
|
|
+ int rc;
|
|
|
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- if (cifsFile->srch_inf.unicode) {
|
|
|
- len = cifs_unicode_bytelen(filename);
|
|
|
- } else {
|
|
|
- /* BB should we make this strnlen of PATH_MAX? */
|
|
|
- len = strnlen(filename, PATH_MAX);
|
|
|
- }
|
|
|
- cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
|
|
|
- } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
|
|
|
- FILE_DIRECTORY_INFO *pFindData =
|
|
|
- (FILE_DIRECTORY_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
|
|
|
- } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
|
|
|
- FILE_FULL_DIRECTORY_INFO *pFindData =
|
|
|
- (FILE_FULL_DIRECTORY_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
|
|
|
- } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
|
|
|
- SEARCH_ID_FULL_DIR_INFO *pFindData =
|
|
|
- (SEARCH_ID_FULL_DIR_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
|
|
|
- } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
|
|
|
- FILE_BOTH_DIRECTORY_INFO *pFindData =
|
|
|
- (FILE_BOTH_DIRECTORY_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- cifsFile->srch_inf.resume_key = pFindData->FileIndex;
|
|
|
- } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
|
|
|
- FIND_FILE_STANDARD_INFO *pFindData =
|
|
|
- (FIND_FILE_STANDARD_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- /* one byte length, no name conversion */
|
|
|
- len = (unsigned int)pFindData->FileNameLength;
|
|
|
- cifsFile->srch_inf.resume_key = pFindData->ResumeKey;
|
|
|
- } else {
|
|
|
- cFYI(1, "Unknown findfirst level %d", level);
|
|
|
- return -EINVAL;
|
|
|
+ rc = cifs_fill_dirent(&de, current_entry, file_info->srch_inf.info_level,
|
|
|
+ file_info->srch_inf.unicode);
|
|
|
+ if (!rc) {
|
|
|
+ file_info->srch_inf.presume_name = de.name;
|
|
|
+ file_info->srch_inf.resume_name_len = de.namelen;
|
|
|
+ file_info->srch_inf.resume_key = de.resume_key;
|
|
|
}
|
|
|
- cifsFile->srch_inf.resume_name_len = len;
|
|
|
- cifsFile->srch_inf.presume_name = filename;
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -605,136 +608,70 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
|
-/* inode num, inode type and filename returned */
|
|
|
-static int cifs_get_name_from_search_buf(struct qstr *pqst,
|
|
|
- char *current_entry, __u16 level, unsigned int unicode,
|
|
|
- struct cifs_sb_info *cifs_sb, unsigned int max_len, __u64 *pinum)
|
|
|
+static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
|
|
|
+ void *dirent, char *scratch_buf, unsigned int max_len)
|
|
|
{
|
|
|
+ struct cifsFileInfo *file_info = file->private_data;
|
|
|
+ struct super_block *sb = file->f_path.dentry->d_sb;
|
|
|
+ struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
|
|
|
+ struct cifs_dirent de = { NULL, };
|
|
|
+ struct cifs_fattr fattr;
|
|
|
+ struct dentry *dentry;
|
|
|
+ struct qstr name;
|
|
|
int rc = 0;
|
|
|
- unsigned int len = 0;
|
|
|
- char *filename;
|
|
|
- struct nls_table *nlt = cifs_sb->local_nls;
|
|
|
-
|
|
|
- *pinum = 0;
|
|
|
-
|
|
|
- if (level == SMB_FIND_FILE_UNIX) {
|
|
|
- FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;
|
|
|
-
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- if (unicode) {
|
|
|
- len = cifs_unicode_bytelen(filename);
|
|
|
- } else {
|
|
|
- /* BB should we make this strnlen of PATH_MAX? */
|
|
|
- len = strnlen(filename, PATH_MAX);
|
|
|
- }
|
|
|
+ ino_t ino;
|
|
|
|
|
|
- *pinum = le64_to_cpu(pFindData->basic.UniqueId);
|
|
|
- } else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {
|
|
|
- FILE_DIRECTORY_INFO *pFindData =
|
|
|
- (FILE_DIRECTORY_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- } else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {
|
|
|
- FILE_FULL_DIRECTORY_INFO *pFindData =
|
|
|
- (FILE_FULL_DIRECTORY_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- } else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {
|
|
|
- SEARCH_ID_FULL_DIR_INFO *pFindData =
|
|
|
- (SEARCH_ID_FULL_DIR_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- *pinum = le64_to_cpu(pFindData->UniqueId);
|
|
|
- } else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {
|
|
|
- FILE_BOTH_DIRECTORY_INFO *pFindData =
|
|
|
- (FILE_BOTH_DIRECTORY_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- len = le32_to_cpu(pFindData->FileNameLength);
|
|
|
- } else if (level == SMB_FIND_FILE_INFO_STANDARD) {
|
|
|
- FIND_FILE_STANDARD_INFO *pFindData =
|
|
|
- (FIND_FILE_STANDARD_INFO *)current_entry;
|
|
|
- filename = &pFindData->FileName[0];
|
|
|
- /* one byte length, no name conversion */
|
|
|
- len = (unsigned int)pFindData->FileNameLength;
|
|
|
- } else {
|
|
|
- cFYI(1, "Unknown findfirst level %d", level);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
+ rc = cifs_fill_dirent(&de, find_entry, file_info->srch_inf.info_level,
|
|
|
+ file_info->srch_inf.unicode);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
|
|
|
- if (len > max_len) {
|
|
|
- cERROR(1, "bad search response length %d past smb end", len);
|
|
|
+ if (de.namelen > max_len) {
|
|
|
+ cERROR(1, "bad search response length %zd past smb end",
|
|
|
+ de.namelen);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- if (unicode) {
|
|
|
- pqst->len = cifs_from_ucs2((char *) pqst->name,
|
|
|
- (__le16 *) filename,
|
|
|
- UNICODE_NAME_MAX,
|
|
|
- min(len, max_len), nlt,
|
|
|
- cifs_sb->mnt_cifs_flags &
|
|
|
- CIFS_MOUNT_MAP_SPECIAL_CHR);
|
|
|
- pqst->len -= nls_nullsize(nlt);
|
|
|
- } else {
|
|
|
- pqst->name = filename;
|
|
|
- pqst->len = len;
|
|
|
- }
|
|
|
- return rc;
|
|
|
-}
|
|
|
-
|
|
|
-static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
|
|
|
- void *direntry, char *scratch_buf, unsigned int max_len)
|
|
|
-{
|
|
|
- int rc = 0;
|
|
|
- struct qstr qstring;
|
|
|
- struct cifsFileInfo *pCifsF;
|
|
|
- u64 inum;
|
|
|
- ino_t ino;
|
|
|
- struct super_block *sb;
|
|
|
- struct cifs_sb_info *cifs_sb;
|
|
|
- struct dentry *tmp_dentry;
|
|
|
- struct cifs_fattr fattr;
|
|
|
-
|
|
|
- /* get filename and len into qstring */
|
|
|
- /* get dentry */
|
|
|
- /* decide whether to create and populate ionde */
|
|
|
- if ((direntry == NULL) || (file == NULL))
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- pCifsF = file->private_data;
|
|
|
-
|
|
|
- if ((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL))
|
|
|
- return -ENOENT;
|
|
|
-
|
|
|
- rc = cifs_entry_is_dot(pfindEntry, pCifsF);
|
|
|
/* skip . and .. since we added them first */
|
|
|
- if (rc != 0)
|
|
|
+ if (cifs_entry_is_dot(&de, file_info->srch_inf.unicode))
|
|
|
return 0;
|
|
|
|
|
|
- sb = file->f_path.dentry->d_sb;
|
|
|
- cifs_sb = CIFS_SB(sb);
|
|
|
-
|
|
|
- qstring.name = scratch_buf;
|
|
|
- rc = cifs_get_name_from_search_buf(&qstring, pfindEntry,
|
|
|
- pCifsF->srch_inf.info_level,
|
|
|
- pCifsF->srch_inf.unicode, cifs_sb,
|
|
|
- max_len, &inum /* returned */);
|
|
|
+ if (file_info->srch_inf.unicode) {
|
|
|
+ struct nls_table *nlt = cifs_sb->local_nls;
|
|
|
|
|
|
- if (rc)
|
|
|
- return rc;
|
|
|
+ name.name = scratch_buf;
|
|
|
+ name.len =
|
|
|
+ cifs_from_ucs2((char *)name.name, (__le16 *)de.name,
|
|
|
+ UNICODE_NAME_MAX,
|
|
|
+ min(de.namelen, (size_t)max_len), nlt,
|
|
|
+ cifs_sb->mnt_cifs_flags &
|
|
|
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
|
|
|
+ name.len -= nls_nullsize(nlt);
|
|
|
+ } else {
|
|
|
+ name.name = de.name;
|
|
|
+ name.len = de.namelen;
|
|
|
+ }
|
|
|
|
|
|
- if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX)
|
|
|
+ switch (file_info->srch_inf.info_level) {
|
|
|
+ case SMB_FIND_FILE_UNIX:
|
|
|
cifs_unix_basic_to_fattr(&fattr,
|
|
|
- &((FILE_UNIX_INFO *) pfindEntry)->basic,
|
|
|
- cifs_sb);
|
|
|
- else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD)
|
|
|
- cifs_std_info_to_fattr(&fattr, (FIND_FILE_STANDARD_INFO *)
|
|
|
- pfindEntry, cifs_sb);
|
|
|
- else
|
|
|
- cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *)
|
|
|
- pfindEntry, cifs_sb);
|
|
|
+ &((FILE_UNIX_INFO *)find_entry)->basic,
|
|
|
+ cifs_sb);
|
|
|
+ break;
|
|
|
+ case SMB_FIND_FILE_INFO_STANDARD:
|
|
|
+ cifs_std_info_to_fattr(&fattr,
|
|
|
+ (FIND_FILE_STANDARD_INFO *)find_entry,
|
|
|
+ cifs_sb);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ cifs_dir_info_to_fattr(&fattr,
|
|
|
+ (FILE_DIRECTORY_INFO *)find_entry,
|
|
|
+ cifs_sb);
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
|
|
|
- fattr.cf_uniqueid = inum;
|
|
|
+ if (de.ino && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
|
|
|
+ fattr.cf_uniqueid = de.ino;
|
|
|
} else {
|
|
|
fattr.cf_uniqueid = iunique(sb, ROOT_I);
|
|
|
cifs_autodisable_serverino(cifs_sb);
|
|
@@ -750,12 +687,12 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
|
|
|
fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
|
|
|
|
|
|
ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
|
|
|
- tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr);
|
|
|
+ dentry = cifs_readdir_lookup(file->f_dentry, &name, &fattr);
|
|
|
|
|
|
- rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,
|
|
|
- ino, fattr.cf_dtype);
|
|
|
+ rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
|
|
|
+ fattr.cf_dtype);
|
|
|
|
|
|
- dput(tmp_dentry);
|
|
|
+ dput(dentry);
|
|
|
return rc;
|
|
|
}
|
|
|
|