[PATCH 1/2] exfat: commonize getting information from dir-entries

From: Tetsuhiro Kohada
Date: Wed Oct 21 2020 - 05:55:43 EST


Move 'getting dir-entries information' from exfat_find() to
exfat_find_dir_entry(), and make it common in exfat_readdir().
And, remove unused parameter in exfat_find_dir_entry().

Signed-off-by: Tetsuhiro Kohada <kohada.t2@xxxxxxxxx>
---
fs/exfat/dir.c | 75 +++++++++++++++++++++++++++++----------------
fs/exfat/exfat_fs.h | 2 +-
fs/exfat/namei.c | 51 +++---------------------------
3 files changed, 53 insertions(+), 75 deletions(-)

diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index 916797077aad..ff809239a540 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -58,6 +58,37 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb,
exfat_free_dentry_set(es, false);
}

+static void exfat_get_dentry_info(struct exfat_sb_info *sbi, struct exfat_dentry de[2],
+ struct exfat_dir_entry *info)
+{
+ info->attr = le16_to_cpu(de[0].dentry.file.attr);
+ info->type = (info->attr & ATTR_SUBDIR) ? TYPE_DIR : TYPE_FILE;
+
+ exfat_get_entry_time(sbi, &info->crtime,
+ de[0].dentry.file.create_tz,
+ de[0].dentry.file.create_time,
+ de[0].dentry.file.create_date,
+ de[0].dentry.file.create_time_cs);
+ exfat_get_entry_time(sbi, &info->mtime,
+ de[0].dentry.file.modify_tz,
+ de[0].dentry.file.modify_time,
+ de[0].dentry.file.modify_date,
+ de[0].dentry.file.modify_time_cs);
+ exfat_get_entry_time(sbi, &info->atime,
+ de[0].dentry.file.access_tz,
+ de[0].dentry.file.access_time,
+ de[0].dentry.file.access_date,
+ 0);
+
+ info->flags = de[1].dentry.stream.flags;
+ info->start_clu = le32_to_cpu(de[1].dentry.stream.start_clu);
+ info->size = le64_to_cpu(de[1].dentry.stream.valid_size);
+ if ((info->type == TYPE_FILE) && (info->size == 0)) {
+ info->flags = ALLOC_NO_FAT_CHAIN;
+ info->start_clu = EXFAT_EOF_CLUSTER;
+ }
+}
+
/* read a directory entry from the opened directory */
static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_entry *dir_entry)
{
@@ -66,7 +97,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
sector_t sector;
struct exfat_chain dir, clu;
struct exfat_uni_name uni_name;
- struct exfat_dentry *ep;
+ struct exfat_dentry *ep, de[2];
struct super_block *sb = inode->i_sb;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
struct exfat_inode_info *ei = EXFAT_I(inode);
@@ -128,22 +159,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
}

num_ext = ep->dentry.file.num_ext;
- dir_entry->attr = le16_to_cpu(ep->dentry.file.attr);
- exfat_get_entry_time(sbi, &dir_entry->crtime,
- ep->dentry.file.create_tz,
- ep->dentry.file.create_time,
- ep->dentry.file.create_date,
- ep->dentry.file.create_time_cs);
- exfat_get_entry_time(sbi, &dir_entry->mtime,
- ep->dentry.file.modify_tz,
- ep->dentry.file.modify_time,
- ep->dentry.file.modify_date,
- ep->dentry.file.modify_time_cs);
- exfat_get_entry_time(sbi, &dir_entry->atime,
- ep->dentry.file.access_tz,
- ep->dentry.file.access_time,
- ep->dentry.file.access_date,
- 0);
+ de[0] = *ep;

*uni_name.name = 0x0;
exfat_get_uniname_from_ext_entry(sb, &dir, dentry,
@@ -156,10 +172,10 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent
ep = exfat_get_dentry(sb, &clu, i + 1, &bh, NULL);
if (!ep)
return -EIO;
- dir_entry->size =
- le64_to_cpu(ep->dentry.stream.valid_size);
+ de[1] = *ep;
dir_entry->entry = dentry;
brelse(bh);
+ exfat_get_dentry_info(sbi, de, dir_entry);

ei->hint_bmap.off = dentry >> dentries_per_clu_bits;
ei->hint_bmap.clu = clu.dir;
@@ -913,7 +929,7 @@ enum {
*/
int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
- int num_entries, unsigned int type)
+ int num_entries, struct exfat_dir_entry *info)
{
int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len;
int order, step, name_len = 0;
@@ -924,6 +940,7 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
struct exfat_hint *hint_stat = &ei->hint_stat;
struct exfat_hint_femp candi_empty;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
+ struct exfat_dentry de[2];

dentries_per_clu = sbi->dentries_per_clu;

@@ -989,11 +1006,9 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
candi_empty.eidx = EXFAT_HINT_NONE;

if (entry_type == TYPE_FILE || entry_type == TYPE_DIR) {
- step = DIRENT_STEP_FILE;
- if (type == TYPE_ALL || type == entry_type) {
- num_ext = ep->dentry.file.num_ext;
- step = DIRENT_STEP_STRM;
- }
+ num_ext = ep->dentry.file.num_ext;
+ de[0] = *ep;
+ step = DIRENT_STEP_STRM;
brelse(bh);
continue;
}
@@ -1015,6 +1030,7 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
step = DIRENT_STEP_NAME;
order = 1;
name_len = 0;
+ de[1] = *ep;
}
brelse(bh);
continue;
@@ -1096,6 +1112,11 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
return -ENOENT;

found:
+ info->dir = *p_dir;
+ info->entry = dentry - num_ext;
+ info->num_subdirs = 0;
+ exfat_get_dentry_info(sbi, de, info);
+
/* next dentry we'll find is out of this cluster */
if (!((dentry + 1) & (dentries_per_clu - 1))) {
int ret = 0;
@@ -1113,13 +1134,13 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
/* just initialized hint_stat */
hint_stat->clu = p_dir->dir;
hint_stat->eidx = 0;
- return (dentry - num_ext);
+ return 0;
}
}

hint_stat->clu = clu.dir;
hint_stat->eidx = dentry + 1;
- return dentry - num_ext;
+ return 0;
}

int exfat_count_ext_entries(struct super_block *sb, struct exfat_chain *p_dir,
diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
index b8f0e829ecbd..f1402fed3302 100644
--- a/fs/exfat/exfat_fs.h
+++ b/fs/exfat/exfat_fs.h
@@ -450,7 +450,7 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es);
int exfat_calc_num_entries(struct exfat_uni_name *p_uniname);
int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname,
- int num_entries, unsigned int type);
+ int num_entries, struct exfat_dir_entry *info);
int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu);
int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir,
int entry, sector_t *sector, int *offset);
diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c
index 2932b23a3b6c..54f54624d7e5 100644
--- a/fs/exfat/namei.c
+++ b/fs/exfat/namei.c
@@ -588,14 +588,12 @@ static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
static int exfat_find(struct inode *dir, struct qstr *qname,
struct exfat_dir_entry *info)
{
- int ret, dentry, num_entries, count;
+ int ret, num_entries, count;
struct exfat_chain cdir;
struct exfat_uni_name uni_name;
struct super_block *sb = dir->i_sb;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
struct exfat_inode_info *ei = EXFAT_I(dir);
- struct exfat_dentry *ep, *ep2;
- struct exfat_entry_set_cache *es;

if (qname->len == 0)
return -ENOENT;
@@ -618,50 +616,9 @@ static int exfat_find(struct inode *dir, struct qstr *qname,
}

/* search the file name for directories */
- dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name,
- num_entries, TYPE_ALL);
-
- if (dentry < 0)
- return dentry; /* -error value */
-
- info->dir = cdir;
- info->entry = dentry;
- info->num_subdirs = 0;
-
- es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES);
- if (!es)
- return -EIO;
- ep = exfat_get_dentry_cached(es, 0);
- ep2 = exfat_get_dentry_cached(es, 1);
-
- info->type = exfat_get_entry_type(ep);
- info->attr = le16_to_cpu(ep->dentry.file.attr);
- info->size = le64_to_cpu(ep2->dentry.stream.valid_size);
- if ((info->type == TYPE_FILE) && (info->size == 0)) {
- info->flags = ALLOC_NO_FAT_CHAIN;
- info->start_clu = EXFAT_EOF_CLUSTER;
- } else {
- info->flags = ep2->dentry.stream.flags;
- info->start_clu =
- le32_to_cpu(ep2->dentry.stream.start_clu);
- }
-
- exfat_get_entry_time(sbi, &info->crtime,
- ep->dentry.file.create_tz,
- ep->dentry.file.create_time,
- ep->dentry.file.create_date,
- ep->dentry.file.create_time_cs);
- exfat_get_entry_time(sbi, &info->mtime,
- ep->dentry.file.modify_tz,
- ep->dentry.file.modify_time,
- ep->dentry.file.modify_date,
- ep->dentry.file.modify_time_cs);
- exfat_get_entry_time(sbi, &info->atime,
- ep->dentry.file.access_tz,
- ep->dentry.file.access_time,
- ep->dentry.file.access_date,
- 0);
- exfat_free_dentry_set(es, false);
+ ret = exfat_find_dir_entry(sb, ei, &cdir, &uni_name, num_entries, info);
+ if (ret)
+ return ret; /* -error value */

if (ei->start_clu == EXFAT_FREE_CLUSTER) {
exfat_fs_error(sb,
--
2.25.1