> 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...@gmail.com>

I can not apply this patch to exfat dev tree. Could you please check it ?
patching file fs/exfat/dir.c
Hunk #1 succeeded at 491 (offset -5 lines).
Hunk #2 succeeded at 500 (offset -5 lines).
Hunk #3 succeeded at 508 (offset -5 lines).
Hunk #4 FAILED at 600.
Hunk #5 succeeded at 1000 (offset -47 lines).
1 out of 5 hunks FAILED -- saving rejects to file fs/exfat/dir.c.rej
patching file fs/exfat/exfat_fs.h
Hunk #1 succeeded at 137 (offset -2 lines).
Hunk #2 succeeded at 512 (offset -3 lines).
patching file fs/exfat/misc.c
patching file fs/exfat/nls.c

Thanks!
> ---
>  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 b5a237c33d50..b673362a895c 
> 100644
> --- a/fs/exfat/dir.c
> +++ b/fs/exfat/dir.c
> @@ -496,7 +496,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;
> 
> @@ -505,7 +505,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); @@ 
> -513,7 +513,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);
>       }
> @@ -600,10 +600,10 @@ int exfat_update_dir_chksum_with_entry_set(struct 
> super_block *sb,
>       int chksum_type = CS_DIR_ENTRY, i, num_entries = es->num_entries;
>       unsigned int buf_off = (off - es->offset);
>       unsigned int remaining_byte_in_sector, copy_entries, clu;
> -     unsigned short chksum = 0;
> +     u16 chksum = 0;
> 
>       for (i = 0; i < num_entries; i++) {
> -             chksum = exfat_calc_chksum_2byte(&es->entries[i], DENTRY_SIZE,
> +             chksum = exfat_calc_chksum16(&es->entries[i], DENTRY_SIZE,
>                       chksum, chksum_type);
>               chksum_type = CS_DEFAULT;
>       }
> @@ -1047,7 +1047,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 
> 15817281b3c8..993d13bbebec 100644
> --- a/fs/exfat/exfat_fs.h
> +++ b/fs/exfat/exfat_fs.h
> @@ -139,7 +139,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;
>  };
> 
> @@ -515,8 +515,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


Reply via email to