Message ID | 20200525115052.19243-4-kohada.t2@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/4] exfat: redefine PBR as boot_sector | expand |
> 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> 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
Thank you for your comment. > 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 II tried applying patch to dev-tree (4c4dbb6ad8e8). -The .patch file I sent -mbox file downloaded from archive But I can't reproduce the error. (Both succeed) How do you reproduce the error? BR
2020-05-27 16:39 GMT+09:00, Tetsuhiro Kohada <kohada.t2@gmail.com>: > Thank you for your comment. > >> 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 > > II tried applying patch to dev-tree (4c4dbb6ad8e8). > -The .patch file I sent > -mbox file downloaded from archive > But I can't reproduce the error. (Both succeed) > How do you reproduce the error? I tried to appy your patches in the following order. 1. [PATCH] exfat: optimize dir-cache 2. [PATCH 1/4] exfat: redefine PBR as boot_sector 3. [PATCH 2/4] exfat: separate the boot sector analysis 4. [PATCH 3/4] exfat: add boot region verification 5. [PATCH 4/4] exfat: standardize checksum calculation Thanks! > > BR >
>> II tried applying patch to dev-tree (4c4dbb6ad8e8). >> -The .patch file I sent >> -mbox file downloaded from archive >> But I can't reproduce the error. (Both succeed) >> How do you reproduce the error? > I tried to appy your patches in the following order. > 1. [PATCH] exfat: optimize dir-cache > 2. [PATCH 1/4] exfat: redefine PBR as boot_sector > 3. [PATCH 2/4] exfat: separate the boot sector analysis > 4. [PATCH 3/4] exfat: add boot region verification > 5. [PATCH 4/4] exfat: standardize checksum calculation I was able to reproduce it. The dir-cache patch was created based on the HEAD of dev-tree. The 4 patches for boot_sector were also created based on the HEAD of dev-tree. (at physically separated place) I'm sorry I didn't check any conflicts with these patches. I'll repost the patch, based on the dir-cache patched dev-tree. If dir-cache patch will merge into dev-tree, should I wait until then? BR
> >> II tried applying patch to dev-tree (4c4dbb6ad8e8). > >> -The .patch file I sent > >> -mbox file downloaded from archive > >> But I can't reproduce the error. (Both succeed) How do you reproduce > >> the error? > > I tried to appy your patches in the following order. > > 1. [PATCH] exfat: optimize dir-cache > > 2. [PATCH 1/4] exfat: redefine PBR as boot_sector 3. [PATCH 2/4] > > exfat: separate the boot sector analysis 4. [PATCH 3/4] exfat: add > > boot region verification 5. [PATCH 4/4] exfat: standardize checksum > > calculation > > I was able to reproduce it. > > The dir-cache patch was created based on the HEAD of dev-tree. > The 4 patches for boot_sector were also created based on the HEAD of dev-tree. > (at physically separated place) > > I'm sorry I didn't check any conflicts with these patches. > > I'll repost the patch, based on the dir-cache patched dev-tree. > If dir-cache patch will merge into dev-tree, should I wait until then? I will apply them after testing at once if you send updated 5 patches again. Thanks! > > BR
>> I'll repost the patch, based on the dir-cache patched dev-tree. >> If dir-cache patch will merge into dev-tree, should I wait until then? > I will apply them after testing at once if you send updated 5 patches again. I resend patches for boot_sector. However, the dir-cache patch hasn't changed, so I haven't reposted it. BR
2020-05-28 19:09 GMT+09:00, Tetsuhiro Kohada <kohada.t2@gmail.com>: >>> I'll repost the patch, based on the dir-cache patched dev-tree. >>> If dir-cache patch will merge into dev-tree, should I wait until then? >> I will apply them after testing at once if you send updated 5 patches >> again. > > I resend patches for boot_sector. > However, the dir-cache patch hasn't changed, so I haven't reposted it. Well, I leave a comment for this patch. > > BR >
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);
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> --- 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(-)