From: Tetsuhiro Kohada <kohada.t2@gmail.com>
To: kohada.t2@gmail.com
Cc: kohada.tetsuhiro@dc.mitsubishielectric.co.jp,
mori.takahiro@ab.mitsubishielectric.co.jp,
motai.hirotaka@aj.mitsubishielectric.co.jp,
Namjae Jeon <namjae.jeon@samsung.com>,
Sungjong Seo <sj1557.seo@samsung.com>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 2/2] exfat: unify name extraction
Date: Thu, 6 Aug 2020 14:56:53 +0900 [thread overview]
Message-ID: <20200806055653.9329-2-kohada.t2@gmail.com> (raw)
In-Reply-To: <20200806055653.9329-1-kohada.t2@gmail.com>
Name extraction in exfat_find_dir_entry() also doesn't care NameLength,
so the name may be incorrect.
Replace the name extraction in exfat_find_dir_entry() with using
exfat_entry_set_cache and exfat_get_uniname_from_name_entries(),
like exfat_readdir().
Replace the name extraction with using exfat_entry_set_cache and
exfat_get_uniname_from_name_entries(), like exfat_readdir().
And, remove unused functions/parameters.
** This patch depends on:
'[PATCH v3] exfat: integrates dir-entry getting and validation'.
Signed-off-by: Tetsuhiro Kohada <kohada.t2@gmail.com>
---
fs/exfat/dir.c | 161 ++++++++++----------------------------------
fs/exfat/exfat_fs.h | 2 +-
fs/exfat/namei.c | 4 +-
3 files changed, 38 insertions(+), 129 deletions(-)
diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index 545bb73b95e9..c9715c7a55a1 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -10,24 +10,6 @@
#include "exfat_raw.h"
#include "exfat_fs.h"
-static int exfat_extract_uni_name(struct exfat_dentry *ep,
- unsigned short *uniname)
-{
- int i, len = 0;
-
- for (i = 0; i < EXFAT_FILE_NAME_LEN; i++) {
- *uniname = le16_to_cpu(ep->dentry.name.unicode_0_14[i]);
- if (*uniname == 0x0)
- return len;
- uniname++;
- len++;
- }
-
- *uniname = 0x0;
- return len;
-
-}
-
static int exfat_get_uniname_from_name_entries(struct exfat_entry_set_cache *es,
struct exfat_uni_name *uniname)
{
@@ -869,13 +851,6 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb,
return NULL;
}
-enum {
- DIRENT_STEP_FILE,
- DIRENT_STEP_STRM,
- DIRENT_STEP_NAME,
- DIRENT_STEP_SECD,
-};
-
/*
* return values:
* >= 0 : return dir entiry position with the name in dir
@@ -885,13 +860,12 @@ 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)
{
- int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len;
- int order, step, name_len = 0;
+ int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0;
+ int name_len = 0;
int dentries_per_clu, num_empty = 0;
unsigned int entry_type;
- unsigned short *uniname = NULL;
struct exfat_chain clu;
struct exfat_hint *hint_stat = &ei->hint_stat;
struct exfat_hint_femp candi_empty;
@@ -909,27 +883,33 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
candi_empty.eidx = EXFAT_HINT_NONE;
rewind:
- order = 0;
- step = DIRENT_STEP_FILE;
while (clu.dir != EXFAT_EOF_CLUSTER) {
i = dentry & (dentries_per_clu - 1);
for (; i < dentries_per_clu; i++, dentry++) {
struct exfat_dentry *ep;
struct buffer_head *bh;
+ struct exfat_entry_set_cache *es;
+ struct exfat_uni_name uni_name;
+ u16 name_hash;
if (rewind && dentry == end_eidx)
goto not_found;
+ /* skip secondary dir-entries in previous dir-entry set */
+ if (num_ext) {
+ num_ext--;
+ continue;
+ }
+
ep = exfat_get_dentry(sb, &clu, i, &bh, NULL);
if (!ep)
return -EIO;
entry_type = exfat_get_entry_type(ep);
+ brelse(bh);
if (entry_type == TYPE_UNUSED ||
entry_type == TYPE_DELETED) {
- step = DIRENT_STEP_FILE;
-
num_empty++;
if (candi_empty.eidx == EXFAT_HINT_NONE &&
num_empty == 1) {
@@ -954,7 +934,6 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
}
}
- brelse(bh);
if (entry_type == TYPE_UNUSED)
goto not_found;
continue;
@@ -963,80 +942,38 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
num_empty = 0;
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;
- }
- brelse(bh);
+ if (entry_type != TYPE_FILE && entry_type != TYPE_DIR)
continue;
- }
-
- if (entry_type == TYPE_STREAM) {
- u16 name_hash;
- if (step != DIRENT_STEP_STRM) {
- step = DIRENT_STEP_FILE;
- brelse(bh);
- continue;
- }
- step = DIRENT_STEP_FILE;
- name_hash = le16_to_cpu(
- ep->dentry.stream.name_hash);
- if (p_uniname->name_hash == name_hash &&
- p_uniname->name_len ==
- ep->dentry.stream.name_len) {
- step = DIRENT_STEP_NAME;
- order = 1;
- name_len = 0;
- }
- brelse(bh);
+ es = exfat_get_dentry_set(sb, &ei->dir, dentry, ES_2_ENTRIES);
+ if (!es)
continue;
- }
- brelse(bh);
- if (entry_type == TYPE_NAME) {
- unsigned short entry_uniname[16], unichar;
-
- if (step != DIRENT_STEP_NAME) {
- step = DIRENT_STEP_FILE;
- continue;
- }
-
- if (++order == 2)
- uniname = p_uniname->name;
- else
- uniname += EXFAT_FILE_NAME_LEN;
-
- len = exfat_extract_uni_name(ep, entry_uniname);
- name_len += len;
-
- unichar = *(uniname+len);
- *(uniname+len) = 0x0;
+ num_ext = es->de_file->num_ext;
+ name_hash = le16_to_cpu(es->de_stream->name_hash);
+ name_len = es->de_stream->name_len;
+ exfat_free_dentry_set(es, false);
- if (exfat_uniname_ncmp(sb, uniname,
- entry_uniname, len)) {
- step = DIRENT_STEP_FILE;
- } else if (p_uniname->name_len == name_len) {
- if (order == num_ext)
- goto found;
- step = DIRENT_STEP_SECD;
- }
+ if (p_uniname->name_hash != name_hash ||
+ p_uniname->name_len != name_len)
+ continue;
- *(uniname+len) = unichar;
+ es = exfat_get_dentry_set(sb, &ei->dir, dentry, ES_ALL_ENTRIES);
+ if (!es)
continue;
- }
- if (entry_type &
- (TYPE_CRITICAL_SEC | TYPE_BENIGN_SEC)) {
- if (step == DIRENT_STEP_SECD) {
- if (++order == num_ext)
- goto found;
- continue;
- }
+ exfat_get_uniname_from_name_entries(es, &uni_name);
+ exfat_free_dentry_set(es, false);
+
+ if (!exfat_uniname_ncmp(sb,
+ p_uniname->name,
+ uni_name.name,
+ name_len)) {
+ /* set the last used position as hint */
+ hint_stat->clu = clu.dir;
+ hint_stat->eidx = dentry;
+ return dentry;
}
- step = DIRENT_STEP_FILE;
}
if (clu.flags == ALLOC_NO_FAT_CHAIN) {
@@ -1069,32 +1006,6 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
hint_stat->clu = p_dir->dir;
hint_stat->eidx = 0;
return -ENOENT;
-
-found:
- /* next dentry we'll find is out of this cluster */
- if (!((dentry + 1) & (dentries_per_clu - 1))) {
- int ret = 0;
-
- if (clu.flags == ALLOC_NO_FAT_CHAIN) {
- if (--clu.size > 0)
- clu.dir++;
- else
- clu.dir = EXFAT_EOF_CLUSTER;
- } else {
- ret = exfat_get_next_cluster(sb, &clu.dir);
- }
-
- if (ret || clu.dir == EXFAT_EOF_CLUSTER) {
- /* just initialized hint_stat */
- hint_stat->clu = p_dir->dir;
- hint_stat->eidx = 0;
- return (dentry - num_ext);
- }
- }
-
- hint_stat->clu = clu.dir;
- hint_stat->eidx = dentry + 1;
- return dentry - num_ext;
}
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 b88b7abc25bd..62a4768a4f6e 100644
--- a/fs/exfat/exfat_fs.h
+++ b/fs/exfat/exfat_fs.h
@@ -456,7 +456,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);
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 a65d60ef93f4..c59d523547ca 100644
--- a/fs/exfat/namei.c
+++ b/fs/exfat/namei.c
@@ -625,9 +625,7 @@ 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);
-
+ dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name, num_entries);
if ((dentry < 0) && (dentry != -EEXIST))
return dentry; /* -error value */
--
2.25.1
next prev parent reply other threads:[~2020-08-06 11:04 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20200806055718epcas1p33009b21ebf96b48d6e3f819065fade28@epcas1p3.samsung.com>
2020-08-06 5:56 ` [PATCH 1/2] exfat: add NameLength check when extracting name Tetsuhiro Kohada
2020-08-06 5:56 ` Tetsuhiro Kohada [this message]
2020-08-08 17:19 ` [PATCH 2/2] exfat: unify name extraction Sungjong Seo
2020-08-12 6:02 ` Tetsuhiro Kohada
2020-08-21 10:41 ` Sungjong Seo
2020-08-25 10:15 ` Tetsuhiro Kohada
2020-08-08 16:54 ` [PATCH 1/2] exfat: add NameLength check when extracting name Sungjong Seo
2020-08-12 4:53 ` Tetsuhiro Kohada
2020-08-10 6:13 ` Namjae Jeon
2020-08-12 15:04 ` Tetsuhiro Kohada
2020-08-13 2:53 ` Namjae Jeon
2020-08-17 9:26 ` Kohada.Tetsuhiro
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200806055653.9329-2-kohada.t2@gmail.com \
--to=kohada.t2@gmail.com \
--cc=kohada.tetsuhiro@dc.mitsubishielectric.co.jp \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mori.takahiro@ab.mitsubishielectric.co.jp \
--cc=motai.hirotaka@aj.mitsubishielectric.co.jp \
--cc=namjae.jeon@samsung.com \
--cc=sj1557.seo@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.