lkml.org 
[lkml]   [2020]   [Jun]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    SubjectRE: [PATCH 4/4 v3] exfat: standardize checksum calculation
    Date
    > 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 <kohada.t2@gmail.com>

    Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>

    > ---
    > 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, &bh, 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
    > 1ebda90cbdd7..19321773dd07 100644
    > --- a/fs/exfat/nls.c
    > +++ b/fs/exfat/nls.c
    > @@ -527,7 +527,7 @@ static int exfat_utf8_to_utf16(struct super_block *sb,
    >
    > *uniname = '\0';
    > 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);
    >
    > if (p_lossy)
    > @@ -623,7 +623,7 @@ static int exfat_nls_to_ucs2(struct super_block *sb,
    >
    > *uniname = '\0';
    > 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);
    >
    > if (p_lossy)
    > @@ -655,7 +655,8 @@ static int exfat_load_upcase_table(struct super_block
    > *sb, {
    > struct exfat_sb_info *sbi = EXFAT_SB(sb);
    > unsigned int sect_size = sb->s_blocksize;
    > - unsigned int i, index = 0, checksum = 0;
    > + unsigned int i, index = 0;
    > + u32 chksum = 0;
    > int ret;
    > unsigned char skip = false;
    > unsigned short *upcase_table;
    > @@ -681,13 +682,6 @@ static int exfat_load_upcase_table(struct super_block
    > *sb,
    > for (i = 0; i < sect_size && index <= 0xFFFF; i += 2) {
    > 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) {
    > index += uni;
    > skip = false;
    > @@ -701,13 +695,14 @@ static int exfat_load_upcase_table(struct
    > super_block *sb,
    > }
    > }
    > 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;
    >
    > 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;
    > free_table:
    > exfat_free_upcase_table(sbi);
    > --
    > 2.25.1


    \
     
     \ /
      Last update: 2020-06-01 14:22    [W:2.785 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site