[PATCH 5/5] staging: exfat: standardize checksum calculation

From: Tetsuhiro Kohada
Date: Wed Mar 11 2020 - 06:52:59 EST


- Remove redundant code of calc_checksum_2byte() and rename to calc_checksum16.
- Replace checksum calculation in __load_upcase_table() with calc_checksum32().

Reviewed-by: Takahiro Mori <Mori.Takahiro@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Tetsuhiro Kohada <Kohada.Tetsuhiro@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
---
drivers/staging/exfat/exfat.h | 3 ++-
drivers/staging/exfat/exfat_core.c | 40 ++++++++----------------------
drivers/staging/exfat/exfat_nls.c | 3 +--
3 files changed, 14 insertions(+), 32 deletions(-)

diff --git a/drivers/staging/exfat/exfat.h b/drivers/staging/exfat/exfat.h
index 95c2a6ef0e71..4e6e6c4b20e5 100644
--- a/drivers/staging/exfat/exfat.h
+++ b/drivers/staging/exfat/exfat.h
@@ -601,7 +601,8 @@ bool is_dir_empty(struct super_block *sb, struct chain_t *p_dir);
/* name conversion functions */
s32 get_num_entries(struct super_block *sb, struct chain_t *p_dir,
struct uni_name_t *p_uniname, s32 *entries);
-u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type);
+u16 calc_checksum16(void *data, int len, u16 chksum, int type);
+u32 calc_checksum32(void *data, int len, u32 chksum, int type);

/* name resolution functions */
s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir,
diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c
index 07c876bb1759..d14e9b345903 100644
--- a/drivers/staging/exfat/exfat_core.c
+++ b/drivers/staging/exfat/exfat_core.c
@@ -588,14 +588,6 @@ static s32 __load_upcase_table(struct super_block *sb, sector_t sector,

for (i = 0; i < p_bd->sector_size && index <= 0xFFFF; i += 2) {
uni = GET16(((u8 *)tmp_bh->b_data) + i);
-
- checksum = ((checksum & 1) ? 0x80000000 : 0) +
- (checksum >> 1) + *(((u8 *)tmp_bh->b_data) +
- i);
- checksum = ((checksum & 1) ? 0x80000000 : 0) +
- (checksum >> 1) + *(((u8 *)tmp_bh->b_data) +
- (i + 1));
-
if (skip) {
pr_debug("skip from 0x%X ", index);
index += uni;
@@ -626,6 +618,8 @@ static s32 __load_upcase_table(struct super_block *sb, sector_t sector,
index++;
}
}
+ checksum = calc_checksum32(tmp_bh->b_data, i, checksum,
+ CS_DEFAULT);
}
if (index >= 0xFFFF && utbl_checksum == checksum) {
if (tmp_bh)
@@ -1096,8 +1090,7 @@ void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir,
exfat_buf_lock(sb, sector);

num_entries = (s32)file_ep->num_ext + 1;
- chksum = calc_checksum_2byte((void *)file_ep, DENTRY_SIZE, 0,
- CS_DIR_ENTRY);
+ chksum = calc_checksum16(file_ep, DENTRY_SIZE, 0, CS_DIR_ENTRY);

for (i = 1; i < num_entries; i++) {
ep = get_entry_in_dir(sb, p_dir, entry + i, NULL);
@@ -1106,8 +1099,7 @@ void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir,
return;
}

- chksum = calc_checksum_2byte((void *)ep, DENTRY_SIZE, chksum,
- CS_DEFAULT);
+ chksum = calc_checksum16(ep, DENTRY_SIZE, chksum, CS_DEFAULT);
}

SET16_A(file_ep->checksum, chksum);
@@ -1192,8 +1184,7 @@ void update_dir_checksum_with_entry_set(struct super_block *sb,
ep = (struct dentry_t *)&es->__buf;
for (i = 0; i < es->num_entries; i++) {
pr_debug("%s ep %p\n", __func__, ep);
- chksum = calc_checksum_2byte((void *)ep, DENTRY_SIZE, chksum,
- chksum_type);
+ chksum = calc_checksum16(ep, DENTRY_SIZE, chksum, chksum_type);
ep++;
chksum_type = CS_DEFAULT;
}
@@ -1997,25 +1988,16 @@ s32 exfat_calc_num_entries(struct uni_name_t *p_uniname)
return (len - 1) / 15 + 3;
}

-u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type)
+u16 calc_checksum16(void *data, int len, u16 chksum, int type)
{
int i;
u8 *c = (u8 *)data;

- switch (type) {
- case CS_DIR_ENTRY:
- for (i = 0; i < len; i++, c++) {
- if ((i == 2) || (i == 3))
- continue;
- chksum = (((chksum & 1) << 15) |
- ((chksum & 0xFFFE) >> 1)) + (u16)*c;
- }
- break;
- default
- :
- for (i = 0; i < len; i++, c++)
- chksum = (((chksum & 1) << 15) |
- ((chksum & 0xFFFE) >> 1)) + (u16)*c;
+ for (i = 0; i < len; i++, c++) {
+ if (unlikely(type == CS_DIR_ENTRY &&
+ (i == 2 || i == 3)))
+ continue;
+ chksum = ((chksum & 1) << 15 | chksum >> 1) + (u16)*c;
}
return chksum;
}
diff --git a/drivers/staging/exfat/exfat_nls.c b/drivers/staging/exfat/exfat_nls.c
index 91e8b0c4dce7..bda6613b4773 100644
--- a/drivers/staging/exfat/exfat_nls.c
+++ b/drivers/staging/exfat/exfat_nls.c
@@ -204,8 +204,7 @@ void nls_cstring_to_uniname(struct super_block *sb,
}

p_uniname->name_len = j;
- p_uniname->name_hash = calc_checksum_2byte(upname, j << 1, 0,
- CS_DEFAULT);
+ p_uniname->name_hash = calc_checksum16(upname, j << 1, 0, CS_DEFAULT);

if (p_lossy)
*p_lossy = lossy;
--
2.25.1