RE: [PATCH 4/4 v3] exfat: standardize checksum calculation

2020-06-01 Thread Sungjong Seo
> To clarify that it is a 16-bit checksum, the parts related to the 16-bit
> checksum are renamed and change type to u16.
> Furthermore, replace checksum calculation in exfat_load_upcase_table()
> with exfat_calc_checksum32().
> 
> Signed-off-by: Tetsuhiro Kohada 

Reviewed-by: Sungjong Seo 

> ---
> Changes in v2:
>  - rebase with patch 'optimize dir-cache' applied Changes in v3:
>  - based on '[PATCH 2/4 v3] exfat: separate the boot sector analysis'
> 
>  fs/exfat/dir.c  | 12 ++--
>  fs/exfat/exfat_fs.h |  5 ++---
>  fs/exfat/misc.c | 10 --
>  fs/exfat/nls.c  | 19 +++
>  4 files changed, 19 insertions(+), 27 deletions(-)
> 
> diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index
> 2902d285bf20..de43534aa299 100644
> --- a/fs/exfat/dir.c
> +++ b/fs/exfat/dir.c
> @@ -491,7 +491,7 @@ int exfat_update_dir_chksum(struct inode *inode,
> struct exfat_chain *p_dir,
>   int ret = 0;
>   int i, num_entries;
>   sector_t sector;
> - unsigned short chksum;
> + u16 chksum;
>   struct exfat_dentry *ep, *fep;
>   struct buffer_head *fbh, *bh;
> 
> @@ -500,7 +500,7 @@ int exfat_update_dir_chksum(struct inode *inode,
> struct exfat_chain *p_dir,
>   return -EIO;
> 
>   num_entries = fep->dentry.file.num_ext + 1;
> - chksum = exfat_calc_chksum_2byte(fep, DENTRY_SIZE, 0, CS_DIR_ENTRY);
> + chksum = exfat_calc_chksum16(fep, DENTRY_SIZE, 0, CS_DIR_ENTRY);
> 
>   for (i = 1; i < num_entries; i++) {
>   ep = exfat_get_dentry(sb, p_dir, entry + i, , NULL); @@ -
> 508,7 +508,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct
> exfat_chain *p_dir,
>   ret = -EIO;
>   goto release_fbh;
>   }
> - chksum = exfat_calc_chksum_2byte(ep, DENTRY_SIZE, chksum,
> + chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum,
>   CS_DEFAULT);
>   brelse(bh);
>   }
> @@ -593,8 +593,8 @@ void exfat_update_dir_chksum_with_entry_set(struct
> exfat_entry_set_cache *es)
> 
>   for (i = 0; i < es->num_entries; i++) {
>   ep = exfat_get_dentry_cached(es, i);
> - chksum = exfat_calc_chksum_2byte(ep, DENTRY_SIZE, chksum,
> -  chksum_type);
> + chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum,
> +  chksum_type);
>   chksum_type = CS_DEFAULT;
>   }
>   ep = exfat_get_dentry_cached(es, 0);
> @@ -1000,7 +1000,7 @@ int exfat_find_dir_entry(struct super_block *sb,
> struct exfat_inode_info *ei,
>   }
> 
>   if (entry_type == TYPE_STREAM) {
> - unsigned short name_hash;
> + u16 name_hash;
> 
>   if (step != DIRENT_STEP_STRM) {
>   step = DIRENT_STEP_FILE;
> diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index
> eebbe5a84b2b..9188985694f0 100644
> --- a/fs/exfat/exfat_fs.h
> +++ b/fs/exfat/exfat_fs.h
> @@ -137,7 +137,7 @@ struct exfat_dentry_namebuf {  struct exfat_uni_name {
>   /* +3 for null and for converting */
>   unsigned short name[MAX_NAME_LENGTH + 3];
> - unsigned short name_hash;
> + u16 name_hash;
>   unsigned char name_len;
>  };
> 
> @@ -512,8 +512,7 @@ void exfat_get_entry_time(struct exfat_sb_info *sbi,
> struct timespec64 *ts,  void exfat_truncate_atime(struct timespec64 *ts);
> void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64
*ts,
>   u8 *tz, __le16 *time, __le16 *date, u8 *time_cs); -unsigned
> short exfat_calc_chksum_2byte(void *data, int len,
> - unsigned short chksum, int type);
> +u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type);
>  u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type);  void
> exfat_update_bh(struct super_block *sb, struct buffer_head *bh, int sync);
> void exfat_chain_set(struct exfat_chain *ec, unsigned int dir, diff --git
> a/fs/exfat/misc.c b/fs/exfat/misc.c index b82d2dd5bd7c..17d41f3d3709
> 100644
> --- a/fs/exfat/misc.c
> +++ b/fs/exfat/misc.c
> @@ -136,17 +136,15 @@ void exfat_truncate_atime(struct timespec64 *ts)
>   ts->tv_nsec = 0;
>  }
> 
> -unsigned short exfat_calc_chksum_2byte(void *data, int len,
> - unsigned short chksum, int type)
> +u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type)
>  {
>   int i;
> - unsigned char *c = (unsigned char *)data;
> + u8 *c = (u8 *)data;
> 
>   for (i = 0; i < len; i++, c++) {
> - if (((i == 2) || (i == 3)) && (type == CS_DIR_ENTRY))
> + if (unlikely(type == CS_DIR_ENTRY && (i == 2 || i == 3)))
>   continue;
> - chksum = (((chksum & 1) << 15) | ((chksum & 0xFFFE) >> 1)) +
> - (unsigned short)*c;
> + 

[PATCH 4/4 v3] exfat: standardize checksum calculation

2020-05-29 Thread Tetsuhiro Kohada
To clarify that it is a 16-bit checksum, the parts related to the 16-bit
checksum are renamed and change type to u16.
Furthermore, replace checksum calculation in exfat_load_upcase_table()
with exfat_calc_checksum32().

Signed-off-by: Tetsuhiro Kohada 
---
Changes in v2:
 - rebase with patch 'optimize dir-cache' applied
Changes in v3:
 - based on '[PATCH 2/4 v3] exfat: separate the boot sector analysis'

 fs/exfat/dir.c  | 12 ++--
 fs/exfat/exfat_fs.h |  5 ++---
 fs/exfat/misc.c | 10 --
 fs/exfat/nls.c  | 19 +++
 4 files changed, 19 insertions(+), 27 deletions(-)

diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index 2902d285bf20..de43534aa299 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -491,7 +491,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct 
exfat_chain *p_dir,
int ret = 0;
int i, num_entries;
sector_t sector;
-   unsigned short chksum;
+   u16 chksum;
struct exfat_dentry *ep, *fep;
struct buffer_head *fbh, *bh;
 
@@ -500,7 +500,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct 
exfat_chain *p_dir,
return -EIO;
 
num_entries = fep->dentry.file.num_ext + 1;
-   chksum = exfat_calc_chksum_2byte(fep, DENTRY_SIZE, 0, CS_DIR_ENTRY);
+   chksum = exfat_calc_chksum16(fep, DENTRY_SIZE, 0, CS_DIR_ENTRY);
 
for (i = 1; i < num_entries; i++) {
ep = exfat_get_dentry(sb, p_dir, entry + i, , NULL);
@@ -508,7 +508,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct 
exfat_chain *p_dir,
ret = -EIO;
goto release_fbh;
}
-   chksum = exfat_calc_chksum_2byte(ep, DENTRY_SIZE, chksum,
+   chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum,
CS_DEFAULT);
brelse(bh);
}
@@ -593,8 +593,8 @@ void exfat_update_dir_chksum_with_entry_set(struct 
exfat_entry_set_cache *es)
 
for (i = 0; i < es->num_entries; i++) {
ep = exfat_get_dentry_cached(es, i);
-   chksum = exfat_calc_chksum_2byte(ep, DENTRY_SIZE, chksum,
-chksum_type);
+   chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum,
+chksum_type);
chksum_type = CS_DEFAULT;
}
ep = exfat_get_dentry_cached(es, 0);
@@ -1000,7 +1000,7 @@ int exfat_find_dir_entry(struct super_block *sb, struct 
exfat_inode_info *ei,
}
 
if (entry_type == TYPE_STREAM) {
-   unsigned short name_hash;
+   u16 name_hash;
 
if (step != DIRENT_STEP_STRM) {
step = DIRENT_STEP_FILE;
diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h
index eebbe5a84b2b..9188985694f0 100644
--- a/fs/exfat/exfat_fs.h
+++ b/fs/exfat/exfat_fs.h
@@ -137,7 +137,7 @@ struct exfat_dentry_namebuf {
 struct exfat_uni_name {
/* +3 for null and for converting */
unsigned short name[MAX_NAME_LENGTH + 3];
-   unsigned short name_hash;
+   u16 name_hash;
unsigned char name_len;
 };
 
@@ -512,8 +512,7 @@ void exfat_get_entry_time(struct exfat_sb_info *sbi, struct 
timespec64 *ts,
 void exfat_truncate_atime(struct timespec64 *ts);
 void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
u8 *tz, __le16 *time, __le16 *date, u8 *time_cs);
-unsigned short exfat_calc_chksum_2byte(void *data, int len,
-   unsigned short chksum, int type);
+u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type);
 u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type);
 void exfat_update_bh(struct super_block *sb, struct buffer_head *bh, int sync);
 void exfat_chain_set(struct exfat_chain *ec, unsigned int dir,
diff --git a/fs/exfat/misc.c b/fs/exfat/misc.c
index b82d2dd5bd7c..17d41f3d3709 100644
--- a/fs/exfat/misc.c
+++ b/fs/exfat/misc.c
@@ -136,17 +136,15 @@ void exfat_truncate_atime(struct timespec64 *ts)
ts->tv_nsec = 0;
 }
 
-unsigned short exfat_calc_chksum_2byte(void *data, int len,
-   unsigned short chksum, int type)
+u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type)
 {
int i;
-   unsigned char *c = (unsigned char *)data;
+   u8 *c = (u8 *)data;
 
for (i = 0; i < len; i++, c++) {
-   if (((i == 2) || (i == 3)) && (type == CS_DIR_ENTRY))
+   if (unlikely(type == CS_DIR_ENTRY && (i == 2 || i == 3)))
continue;
-   chksum = (((chksum & 1) << 15) | ((chksum & 0xFFFE) >> 1)) +
-   (unsigned short)*c;
+   chksum = ((chksum << 15) | (chksum >> 1)) + *c;
}
return chksum;
 }
diff --git a/fs/exfat/nls.c b/fs/exfat/nls.c
index