Commit 5875bf28 authored by Tetsuhiro Kohada's avatar Tetsuhiro Kohada Committed by Namjae Jeon

exfat: standardize checksum calculation

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: default avatarTetsuhiro Kohada <kohada.t2@gmail.com>
Reviewed-by: default avatarSungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: default avatarNamjae Jeon <namjae.jeon@samsung.com>
parent 476189c0
...@@ -491,7 +491,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir, ...@@ -491,7 +491,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir,
int ret = 0; int ret = 0;
int i, num_entries; int i, num_entries;
sector_t sector; sector_t sector;
unsigned short chksum; u16 chksum;
struct exfat_dentry *ep, *fep; struct exfat_dentry *ep, *fep;
struct buffer_head *fbh, *bh; struct buffer_head *fbh, *bh;
...@@ -500,7 +500,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir, ...@@ -500,7 +500,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir,
return -EIO; return -EIO;
num_entries = fep->dentry.file.num_ext + 1; 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++) { for (i = 1; i < num_entries; i++) {
ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, NULL); ep = exfat_get_dentry(sb, p_dir, entry + i, &bh, NULL);
...@@ -508,7 +508,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir, ...@@ -508,7 +508,7 @@ int exfat_update_dir_chksum(struct inode *inode, struct exfat_chain *p_dir,
ret = -EIO; ret = -EIO;
goto release_fbh; goto release_fbh;
} }
chksum = exfat_calc_chksum_2byte(ep, DENTRY_SIZE, chksum, chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum,
CS_DEFAULT); CS_DEFAULT);
brelse(bh); brelse(bh);
} }
...@@ -593,8 +593,8 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es) ...@@ -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++) { for (i = 0; i < es->num_entries; i++) {
ep = exfat_get_dentry_cached(es, i); ep = exfat_get_dentry_cached(es, i);
chksum = exfat_calc_chksum_2byte(ep, DENTRY_SIZE, chksum, chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum,
chksum_type); chksum_type);
chksum_type = CS_DEFAULT; chksum_type = CS_DEFAULT;
} }
ep = exfat_get_dentry_cached(es, 0); 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, ...@@ -1000,7 +1000,7 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei,
} }
if (entry_type == TYPE_STREAM) { if (entry_type == TYPE_STREAM) {
unsigned short name_hash; u16 name_hash;
if (step != DIRENT_STEP_STRM) { if (step != DIRENT_STEP_STRM) {
step = DIRENT_STEP_FILE; step = DIRENT_STEP_FILE;
......
...@@ -137,7 +137,7 @@ struct exfat_dentry_namebuf { ...@@ -137,7 +137,7 @@ struct exfat_dentry_namebuf {
struct exfat_uni_name { struct exfat_uni_name {
/* +3 for null and for converting */ /* +3 for null and for converting */
unsigned short name[MAX_NAME_LENGTH + 3]; unsigned short name[MAX_NAME_LENGTH + 3];
unsigned short name_hash; u16 name_hash;
unsigned char name_len; unsigned char name_len;
}; };
...@@ -512,8 +512,7 @@ void exfat_get_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts, ...@@ -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_truncate_atime(struct timespec64 *ts);
void exfat_set_entry_time(struct exfat_sb_info *sbi, 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); u8 *tz, __le16 *time, __le16 *date, u8 *time_cs);
unsigned short exfat_calc_chksum_2byte(void *data, int len, u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type);
unsigned short chksum, int type);
u32 exfat_calc_chksum32(void *data, int len, u32 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_update_bh(struct super_block *sb, struct buffer_head *bh, int sync);
void exfat_chain_set(struct exfat_chain *ec, unsigned int dir, void exfat_chain_set(struct exfat_chain *ec, unsigned int dir,
......
...@@ -136,17 +136,15 @@ void exfat_truncate_atime(struct timespec64 *ts) ...@@ -136,17 +136,15 @@ void exfat_truncate_atime(struct timespec64 *ts)
ts->tv_nsec = 0; ts->tv_nsec = 0;
} }
unsigned short exfat_calc_chksum_2byte(void *data, int len, u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type)
unsigned short chksum, int type)
{ {
int i; int i;
unsigned char *c = (unsigned char *)data; u8 *c = (u8 *)data;
for (i = 0; i < len; i++, c++) { 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; continue;
chksum = (((chksum & 1) << 15) | ((chksum & 0xFFFE) >> 1)) + chksum = ((chksum << 15) | (chksum >> 1)) + *c;
(unsigned short)*c;
} }
return chksum; return chksum;
} }
......
...@@ -527,7 +527,7 @@ static int exfat_utf8_to_utf16(struct super_block *sb, ...@@ -527,7 +527,7 @@ static int exfat_utf8_to_utf16(struct super_block *sb,
*uniname = '\0'; *uniname = '\0';
p_uniname->name_len = unilen; p_uniname->name_len = unilen;
p_uniname->name_hash = exfat_calc_chksum_2byte(upname, unilen << 1, 0, p_uniname->name_hash = exfat_calc_chksum16(upname, unilen << 1, 0,
CS_DEFAULT); CS_DEFAULT);
if (p_lossy) if (p_lossy)
...@@ -623,7 +623,7 @@ static int exfat_nls_to_ucs2(struct super_block *sb, ...@@ -623,7 +623,7 @@ static int exfat_nls_to_ucs2(struct super_block *sb,
*uniname = '\0'; *uniname = '\0';
p_uniname->name_len = unilen; p_uniname->name_len = unilen;
p_uniname->name_hash = exfat_calc_chksum_2byte(upname, unilen << 1, 0, p_uniname->name_hash = exfat_calc_chksum16(upname, unilen << 1, 0,
CS_DEFAULT); CS_DEFAULT);
if (p_lossy) if (p_lossy)
...@@ -655,7 +655,8 @@ static int exfat_load_upcase_table(struct super_block *sb, ...@@ -655,7 +655,8 @@ static int exfat_load_upcase_table(struct super_block *sb,
{ {
struct exfat_sb_info *sbi = EXFAT_SB(sb); struct exfat_sb_info *sbi = EXFAT_SB(sb);
unsigned int sect_size = sb->s_blocksize; unsigned int sect_size = sb->s_blocksize;
unsigned int i, index = 0, checksum = 0; unsigned int i, index = 0;
u32 chksum = 0;
int ret; int ret;
unsigned char skip = false; unsigned char skip = false;
unsigned short *upcase_table; unsigned short *upcase_table;
...@@ -681,13 +682,6 @@ static int exfat_load_upcase_table(struct super_block *sb, ...@@ -681,13 +682,6 @@ static int exfat_load_upcase_table(struct super_block *sb,
for (i = 0; i < sect_size && index <= 0xFFFF; i += 2) { for (i = 0; i < sect_size && index <= 0xFFFF; i += 2) {
unsigned short uni = get_unaligned_le16(bh->b_data + i); unsigned short uni = get_unaligned_le16(bh->b_data + i);
checksum = ((checksum & 1) ? 0x80000000 : 0) +
(checksum >> 1) +
*(((unsigned char *)bh->b_data) + i);
checksum = ((checksum & 1) ? 0x80000000 : 0) +
(checksum >> 1) +
*(((unsigned char *)bh->b_data) + (i + 1));
if (skip) { if (skip) {
index += uni; index += uni;
skip = false; skip = false;
...@@ -701,13 +695,14 @@ static int exfat_load_upcase_table(struct super_block *sb, ...@@ -701,13 +695,14 @@ static int exfat_load_upcase_table(struct super_block *sb,
} }
} }
brelse(bh); brelse(bh);
chksum = exfat_calc_chksum32(bh->b_data, i, chksum, CS_DEFAULT);
} }
if (index >= 0xFFFF && utbl_checksum == checksum) if (index >= 0xFFFF && utbl_checksum == chksum)
return 0; return 0;
exfat_err(sb, "failed to load upcase table (idx : 0x%08x, chksum : 0x%08x, utbl_chksum : 0x%08x)", exfat_err(sb, "failed to load upcase table (idx : 0x%08x, chksum : 0x%08x, utbl_chksum : 0x%08x)",
index, checksum, utbl_checksum); index, chksum, utbl_checksum);
ret = -EINVAL; ret = -EINVAL;
free_table: free_table:
exfat_free_upcase_table(sbi); exfat_free_upcase_table(sbi);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment