* [PATCH 2/5] staging: exfat: separate and move exFAT-mount core processing.
2020-03-11 10:52 [PATCH 1/5] staging: exfat: conform 'pbr_sector_t' definition to exFAT specification Tetsuhiro Kohada
@ 2020-03-11 10:52 ` Tetsuhiro Kohada
2020-03-11 10:52 ` [PATCH 3/5] staging: exfat: consolidate boot sector analysis Tetsuhiro Kohada
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Tetsuhiro Kohada @ 2020-03-11 10:52 UTC (permalink / raw)
To: Kohada.Tetsuhiro
Cc: Mori.Takahiro, motai.hirotaka, Valdis Kletnieks,
Greg Kroah-Hartman, linux-fsdevel, devel, linux-kernel
Separate the mount process related to the exFAT specification in ffsMountVol() and move it to exfat_mount.c.
- Rename exfat_mount() to read_boot_sector().
- Separate exFAT-mount core process and move to exfat_mount.c as NEW exfat_mount().
- Move free_upcase_table()/free_alloc_bitmap() to exfat_mount.c as exfat_umount().
- Change some functions to static.
This also fixes the exfat_bdev_close() leak. :-)
Reviewed-by: Takahiro Mori <Mori.Takahiro@ab.MitsubishiElectric.co.jp>
Signed-off-by: Tetsuhiro Kohada <Kohada.Tetsuhiro@dc.MitsubishiElectric.co.jp>
---
drivers/staging/exfat/exfat.h | 11 +---
drivers/staging/exfat/exfat_core.c | 82 +++++++++++++++++++++++++++--
drivers/staging/exfat/exfat_super.c | 66 ++---------------------
3 files changed, 83 insertions(+), 76 deletions(-)
diff --git a/drivers/staging/exfat/exfat.h b/drivers/staging/exfat/exfat.h
index 0f730090cb30..95c2a6ef0e71 100644
--- a/drivers/staging/exfat/exfat.h
+++ b/drivers/staging/exfat/exfat.h
@@ -581,14 +581,6 @@ void fs_error(struct super_block *sb);
s32 count_num_clusters(struct super_block *sb, struct chain_t *dir);
void exfat_chain_cont_cluster(struct super_block *sb, u32 chain, s32 len);
-/* allocation bitmap management functions */
-s32 load_alloc_bitmap(struct super_block *sb);
-void free_alloc_bitmap(struct super_block *sb);
-
-/* upcase table management functions */
-s32 load_upcase_table(struct super_block *sb);
-void free_upcase_table(struct super_block *sb);
-
/* dir entry management functions */
struct timestamp_t *tm_current(struct timestamp_t *tm);
@@ -616,7 +608,8 @@ s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir,
struct uni_name_t *p_uniname);
/* file operation functions */
-s32 exfat_mount(struct super_block *sb, struct boot_sector_t *p_boot);
+s32 exfat_mount(struct super_block *sb);
+void exfat_umount(struct super_block *sb);
s32 create_dir(struct inode *inode, struct chain_t *p_dir,
struct uni_name_t *p_uniname, struct file_id_t *fid);
s32 create_file(struct inode *inode, struct chain_t *p_dir,
diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c
index ca1039b7977c..2d88ce85217c 100644
--- a/drivers/staging/exfat/exfat_core.c
+++ b/drivers/staging/exfat/exfat_core.c
@@ -472,7 +472,7 @@ void exfat_chain_cont_cluster(struct super_block *sb, u32 chain, s32 len)
* Allocation Bitmap Management Functions
*/
-s32 load_alloc_bitmap(struct super_block *sb)
+static s32 load_alloc_bitmap(struct super_block *sb)
{
int i, j, ret;
u32 map_size;
@@ -544,7 +544,7 @@ s32 load_alloc_bitmap(struct super_block *sb)
return -EFSCORRUPTED;
}
-void free_alloc_bitmap(struct super_block *sb)
+static void free_alloc_bitmap(struct super_block *sb)
{
int i;
struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
@@ -561,6 +561,8 @@ void free_alloc_bitmap(struct super_block *sb)
/*
* Upcase table Management Functions
*/
+static void free_upcase_table(struct super_block *sb);
+
static s32 __load_upcase_table(struct super_block *sb, sector_t sector,
u32 num_sectors, u32 utbl_checksum)
{
@@ -706,7 +708,7 @@ static s32 __load_default_upcase_table(struct super_block *sb)
return ret;
}
-s32 load_upcase_table(struct super_block *sb)
+static s32 load_upcase_table(struct super_block *sb)
{
int i;
u32 tbl_clu, tbl_size;
@@ -754,7 +756,7 @@ s32 load_upcase_table(struct super_block *sb)
return __load_default_upcase_table(sb);
}
-void free_upcase_table(struct super_block *sb)
+static void free_upcase_table(struct super_block *sb)
{
u32 i;
struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
@@ -2060,7 +2062,8 @@ s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir,
return 0;
}
-s32 exfat_mount(struct super_block *sb, struct boot_sector_t *p_boot)
+static s32 read_boot_sector(struct super_block *sb,
+ struct boot_sector_t *p_boot)
{
struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
@@ -2104,6 +2107,75 @@ s32 exfat_mount(struct super_block *sb, struct boot_sector_t *p_boot)
return 0;
}
+s32 exfat_mount(struct super_block *sb)
+{
+ int i, ret;
+ struct boot_sector_t *p_boot;
+ struct buffer_head *tmp_bh = NULL;
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ /* read Sector 0 */
+ if (sector_read(sb, 0, &tmp_bh, 1) != 0) {
+ ret = -EIO;
+ goto out;
+ }
+
+ p_boot = (struct boot_sector_t *)tmp_bh->b_data;
+
+ /* check the validity of BOOT sector */
+ if (le16_to_cpu(p_boot->boot_signature) != BOOT_SIGNATURE) {
+ brelse(tmp_bh);
+ ret = -EFSCORRUPTED;
+ goto out;
+ }
+
+ /* fill fs_struct */
+ for (i = 0; i < 53; i++)
+ if (p_boot->must_be_zero[i])
+ break;
+
+ if (i < 53) {
+ /* Not sure how we'd get here, but complain if it does */
+ ret = -EINVAL;
+ pr_info("EXFAT: Attempted to mount VFAT filesystem\n");
+ goto out;
+ } else {
+ ret = read_boot_sector(sb, p_boot);
+ }
+
+ brelse(tmp_bh);
+
+ if (ret)
+ goto out;
+
+ ret = load_alloc_bitmap(sb);
+ if (ret)
+ goto out;
+
+ ret = load_upcase_table(sb);
+ if (ret) {
+ free_alloc_bitmap(sb);
+ goto out;
+ }
+
+ if (p_fs->dev_ejected) {
+ free_upcase_table(sb);
+ free_alloc_bitmap(sb);
+ ret = -EIO;
+ goto out;
+ }
+
+ pr_info("[EXFAT] mounted successfully\n");
+out:
+ return ret;
+}
+
+void exfat_umount(struct super_block *sb)
+{
+ free_upcase_table(sb);
+ free_alloc_bitmap(sb);
+}
+
s32 create_dir(struct inode *inode, struct chain_t *p_dir,
struct uni_name_t *p_uniname, struct file_id_t *fid)
{
diff --git a/drivers/staging/exfat/exfat_super.c b/drivers/staging/exfat/exfat_super.c
index bd257d401f7b..978e1d5172ee 100644
--- a/drivers/staging/exfat/exfat_super.c
+++ b/drivers/staging/exfat/exfat_super.c
@@ -343,9 +343,7 @@ static inline void exfat_save_attr(struct inode *inode, u32 attr)
static int ffsMountVol(struct super_block *sb)
{
- int i, ret;
- struct boot_sector_t *p_boot;
- struct buffer_head *tmp_bh = NULL;
+ int ret;
struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
@@ -370,66 +368,11 @@ static int ffsMountVol(struct super_block *sb)
if (p_bd->sector_size > sb->s_blocksize)
sb_set_blocksize(sb, p_bd->sector_size);
- /* read Sector 0 */
- if (sector_read(sb, 0, &tmp_bh, 1) != 0) {
- ret = -EIO;
- goto out;
- }
-
- p_boot = (struct boot_sector_t *)tmp_bh->b_data;
-
- /* check the validity of BOOT sector */
- if (le16_to_cpu(p_boot->boot_signature) != BOOT_SIGNATURE) {
- brelse(tmp_bh);
- exfat_bdev_close(sb);
- ret = -EFSCORRUPTED;
- goto out;
- }
-
- /* fill fs_struct */
- for (i = 0; i < 53; i++)
- if (p_boot->must_be_zero[i])
- break;
-
- if (i < 53) {
- /* Not sure how we'd get here, but complain if it does */
- ret = -EINVAL;
- pr_info("EXFAT: Attempted to mount VFAT filesystem\n");
- goto out;
- } else {
- ret = exfat_mount(sb, p_boot);
- }
-
- brelse(tmp_bh);
-
- if (ret) {
- exfat_bdev_close(sb);
- goto out;
- }
-
- ret = load_alloc_bitmap(sb);
- if (ret) {
- exfat_bdev_close(sb);
- goto out;
- }
- ret = load_upcase_table(sb);
+ ret = exfat_mount(sb);
+out:
if (ret) {
- free_alloc_bitmap(sb);
exfat_bdev_close(sb);
- goto out;
}
-
- if (p_fs->dev_ejected) {
- free_upcase_table(sb);
- free_alloc_bitmap(sb);
- exfat_bdev_close(sb);
- ret = -EIO;
- goto out;
- }
-
- pr_info("[EXFAT] mounted successfully\n");
-
-out:
mutex_unlock(&z_mutex);
return ret;
@@ -450,8 +393,7 @@ static int ffsUmountVol(struct super_block *sb)
fs_sync(sb, true);
fs_set_vol_flags(sb, VOL_CLEAN);
- free_upcase_table(sb);
- free_alloc_bitmap(sb);
+ exfat_umount(sb);
exfat_fat_release_all(sb);
exfat_buf_release_all(sb);
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/5] staging: exfat: consolidate boot sector analysis
2020-03-11 10:52 [PATCH 1/5] staging: exfat: conform 'pbr_sector_t' definition to exFAT specification Tetsuhiro Kohada
2020-03-11 10:52 ` [PATCH 2/5] staging: exfat: separate and move exFAT-mount core processing Tetsuhiro Kohada
@ 2020-03-11 10:52 ` Tetsuhiro Kohada
2020-03-11 10:52 ` [PATCH 4/5] staging: exfat: add boot region verification Tetsuhiro Kohada
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Tetsuhiro Kohada @ 2020-03-11 10:52 UTC (permalink / raw)
To: Kohada.Tetsuhiro
Cc: Mori.Takahiro, motai.hirotaka, Valdis Kletnieks,
Greg Kroah-Hartman, linux-fsdevel, devel, linux-kernel
Consolidate boot sector analysis into read_boot_sector().
- Move boot sector analysis from exfat_mount() to read_boot_sector().
- Fix num_fats check in read_boot_sector().
- Consolidate p_fs->boot_bh initialization/release into mount/umount.
This fixes vol_flags inconsistency at read failed in fs_set_vol_flags(),
and tmp_bh leak in exfat_mount(). :-)
Reviewed-by: Takahiro Mori <Mori.Takahiro@ab.MitsubishiElectric.co.jp>
Signed-off-by: Tetsuhiro Kohada <Kohada.Tetsuhiro@dc.MitsubishiElectric.co.jp>
---
drivers/staging/exfat/exfat_core.c | 106 ++++++++++++-----------------
1 file changed, 45 insertions(+), 61 deletions(-)
diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c
index 2d88ce85217c..3faa7f35c77c 100644
--- a/drivers/staging/exfat/exfat_core.c
+++ b/drivers/staging/exfat/exfat_core.c
@@ -89,11 +89,6 @@ void fs_set_vol_flags(struct super_block *sb, u32 new_flag)
p_fs->vol_flag = new_flag;
- if (!p_fs->boot_bh) {
- if (sector_read(sb, 0, &p_fs->boot_bh, 1) != 0)
- return;
- }
-
p_boot = (struct boot_sector_t *)p_fs->boot_bh->b_data;
p_boot->vol_flags = cpu_to_le16(new_flag);
@@ -531,8 +526,6 @@ static s32 load_alloc_bitmap(struct super_block *sb)
return ret;
}
}
-
- p_fs->boot_bh = NULL;
return 0;
}
}
@@ -549,9 +542,7 @@ static void free_alloc_bitmap(struct super_block *sb)
int i;
struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
- brelse(p_fs->boot_bh);
-
- for (i = 0; i < p_fs->map_sectors; i++)
+ for (i = 0; i < p_fs->map_sectors && p_fs->vol_amap; i++)
__brelse(p_fs->vol_amap[i]);
kfree(p_fs->vol_amap);
@@ -763,7 +754,7 @@ static void free_upcase_table(struct super_block *sb)
u16 **upcase_table;
upcase_table = p_fs->vol_utbl;
- for (i = 0; i < UTBL_COL_COUNT; i++)
+ for (i = 0; i < UTBL_COL_COUNT && upcase_table; i++)
kfree(upcase_table[i]);
kfree(p_fs->vol_utbl);
@@ -2062,15 +2053,31 @@ s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir,
return 0;
}
-static s32 read_boot_sector(struct super_block *sb,
- struct boot_sector_t *p_boot)
+static int read_boot_sector(struct super_block *sb)
{
struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
+ struct boot_sector_t *p_boot;
+ int i;
+
+ p_boot = (struct boot_sector_t *)p_fs->boot_bh->b_data;
- if (p_boot->num_fats == 0)
+ /* check the validity of BOOT sector */
+ if (le16_to_cpu(p_boot->boot_signature) != BOOT_SIGNATURE)
return -EFSCORRUPTED;
+ /* check the byte range consumed as BPB for FAT12/16/32 volumes */
+ for (i = 0; i < 53; i++) {
+ if (p_boot->must_be_zero[i]) {
+ pr_info("EXFAT: Attempted to mount VFAT filesystem\n");
+ return -EFSCORRUPTED;
+ }
+ }
+
+ if (p_boot->num_fats != 1 && p_boot->num_fats != 2)
+ return -EFSCORRUPTED;
+
+ /* fill fs_info */
p_fs->sectors_per_clu = 1 << p_boot->sectors_per_clu_shift;
p_fs->sectors_per_clu_bits = p_boot->sectors_per_clu_shift;
p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits +
@@ -2080,11 +2087,9 @@ static s32 read_boot_sector(struct super_block *sb,
p_fs->num_FAT_sectors = le32_to_cpu(p_boot->fat_length);
p_fs->FAT1_start_sector = le32_to_cpu(p_boot->fat_offset);
- if (p_boot->num_fats == 1)
- p_fs->FAT2_start_sector = p_fs->FAT1_start_sector;
- else
- p_fs->FAT2_start_sector = p_fs->FAT1_start_sector +
- p_fs->num_FAT_sectors;
+ p_fs->FAT2_start_sector = p_fs->FAT1_start_sector;
+ if (p_boot->num_fats == 2)
+ p_fs->FAT2_start_sector += p_fs->num_FAT_sectors;
p_fs->root_start_sector = le32_to_cpu(p_boot->clu_offset);
p_fs->data_start_sector = p_fs->root_start_sector;
@@ -2109,71 +2114,50 @@ static s32 read_boot_sector(struct super_block *sb,
s32 exfat_mount(struct super_block *sb)
{
- int i, ret;
- struct boot_sector_t *p_boot;
- struct buffer_head *tmp_bh = NULL;
struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+ int ret;
- /* read Sector 0 */
- if (sector_read(sb, 0, &tmp_bh, 1) != 0) {
- ret = -EIO;
- goto out;
- }
-
- p_boot = (struct boot_sector_t *)tmp_bh->b_data;
-
- /* check the validity of BOOT sector */
- if (le16_to_cpu(p_boot->boot_signature) != BOOT_SIGNATURE) {
- brelse(tmp_bh);
- ret = -EFSCORRUPTED;
- goto out;
- }
-
- /* fill fs_struct */
- for (i = 0; i < 53; i++)
- if (p_boot->must_be_zero[i])
- break;
-
- if (i < 53) {
- /* Not sure how we'd get here, but complain if it does */
- ret = -EINVAL;
- pr_info("EXFAT: Attempted to mount VFAT filesystem\n");
- goto out;
- } else {
- ret = read_boot_sector(sb, p_boot);
- }
+ p_fs->vol_utbl = NULL;
+ p_fs->vol_amap = NULL;
- brelse(tmp_bh);
+ /* read Sector 0 */
+ ret = sector_read(sb, 0, &p_fs->boot_bh, 1);
+ if (ret)
+ goto err_out;
+ ret = read_boot_sector(sb);
if (ret)
- goto out;
+ goto err_out;
ret = load_alloc_bitmap(sb);
if (ret)
- goto out;
+ goto err_out;
ret = load_upcase_table(sb);
- if (ret) {
- free_alloc_bitmap(sb);
- goto out;
- }
+ if (ret)
+ goto err_out;
if (p_fs->dev_ejected) {
- free_upcase_table(sb);
- free_alloc_bitmap(sb);
ret = -EIO;
- goto out;
+ goto err_out;
}
pr_info("[EXFAT] mounted successfully\n");
-out:
+ return 0;
+
+err_out:
+ exfat_umount(sb);
return ret;
}
void exfat_umount(struct super_block *sb)
{
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+
free_upcase_table(sb);
free_alloc_bitmap(sb);
+ brelse(p_fs->boot_bh);
+ p_fs->boot_bh = NULL;
}
s32 create_dir(struct inode *inode, struct chain_t *p_dir,
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 4/5] staging: exfat: add boot region verification
2020-03-11 10:52 [PATCH 1/5] staging: exfat: conform 'pbr_sector_t' definition to exFAT specification Tetsuhiro Kohada
2020-03-11 10:52 ` [PATCH 2/5] staging: exfat: separate and move exFAT-mount core processing Tetsuhiro Kohada
2020-03-11 10:52 ` [PATCH 3/5] staging: exfat: consolidate boot sector analysis Tetsuhiro Kohada
@ 2020-03-11 10:52 ` Tetsuhiro Kohada
2020-03-11 10:52 ` [PATCH 5/5] staging: exfat: standardize checksum calculation Tetsuhiro Kohada
2020-03-11 12:05 ` [PATCH 1/5] staging: exfat: conform 'pbr_sector_t' definition to exFAT specification Greg Kroah-Hartman
4 siblings, 0 replies; 6+ messages in thread
From: Tetsuhiro Kohada @ 2020-03-11 10:52 UTC (permalink / raw)
To: Kohada.Tetsuhiro
Cc: Mori.Takahiro, motai.hirotaka, Valdis Kletnieks,
Greg Kroah-Hartman, linux-fsdevel, devel, linux-kernel
Add Boot-Regions verification specified in exFAT specification.
Reviewed-by: Takahiro Mori <Mori.Takahiro@ab.MitsubishiElectric.co.jp>
Signed-off-by: Tetsuhiro Kohada <Kohada.Tetsuhiro@dc.MitsubishiElectric.co.jp>
---
drivers/staging/exfat/exfat_core.c | 69 ++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c
index 3faa7f35c77c..07c876bb1759 100644
--- a/drivers/staging/exfat/exfat_core.c
+++ b/drivers/staging/exfat/exfat_core.c
@@ -2017,7 +2017,20 @@ u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type)
chksum = (((chksum & 1) << 15) |
((chksum & 0xFFFE) >> 1)) + (u16)*c;
}
+ return chksum;
+}
+u32 calc_checksum32(void *data, int len, u32 chksum, int type)
+{
+ int i;
+ u8 *c = (u8 *)data;
+
+ for (i = 0; i < len; i++, c++) {
+ if (unlikely(type == CS_BOOT_SECTOR &&
+ (i == 106 || i == 107 || i == 112)))
+ continue;
+ chksum = ((chksum & 1) << 31 | chksum >> 1) + (u32)*c;
+ }
return chksum;
}
@@ -2053,6 +2066,58 @@ s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir,
return 0;
}
+static int verify_boot_region(struct super_block *sb)
+{
+ struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
+ struct buffer_head *tmp_bh = NULL;
+ u32 chksum = 0, *p_signatue, *p_chksum;
+ int sn = 0, i, ret;
+
+ /* read boot sector sub-regions */
+ ret = sector_read(sb, sn++, &tmp_bh, 1);
+ if (ret)
+ goto out;
+
+ chksum = calc_checksum32(tmp_bh->b_data, p_bd->sector_size,
+ chksum, CS_BOOT_SECTOR);
+
+ while (sn < 11) {
+ ret = sector_read(sb, sn++, &tmp_bh, 1);
+ if (ret)
+ goto out;
+
+ chksum = calc_checksum32(tmp_bh->b_data, p_bd->sector_size,
+ chksum, CS_DEFAULT);
+
+ /* skip OEM Parameters & Reserved sub-regions */
+ if (sn >= 9)
+ continue;
+
+ /* extended boot sector sub-regions */
+ p_signatue = (u32 *)(tmp_bh->b_data + p_bd->sector_size - 4);
+ if (le32_to_cpu(*p_signatue) != EXBOOT_SIGNATURE) {
+ ret = -EFSCORRUPTED;
+ goto out;
+ }
+ }
+
+ /* boot checksum sub-regions */
+ ret = sector_read(sb, sn++, &tmp_bh, 1);
+ if (ret)
+ goto out;
+
+ p_chksum = (u32 *)tmp_bh->b_data;
+ for (i = 0; i < p_bd->sector_size / 4; i++) {
+ if (le32_to_cpu(*p_chksum) != chksum) {
+ ret = -EFSCORRUPTED;
+ goto out;
+ }
+ }
+out:
+ brelse(tmp_bh);
+ return ret;
+}
+
static int read_boot_sector(struct super_block *sb)
{
struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
@@ -2129,6 +2194,10 @@ s32 exfat_mount(struct super_block *sb)
if (ret)
goto err_out;
+ ret = verify_boot_region(sb);
+ if (ret)
+ goto err_out;
+
ret = load_alloc_bitmap(sb);
if (ret)
goto err_out;
--
2.25.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 5/5] staging: exfat: standardize checksum calculation
2020-03-11 10:52 [PATCH 1/5] staging: exfat: conform 'pbr_sector_t' definition to exFAT specification Tetsuhiro Kohada
` (2 preceding siblings ...)
2020-03-11 10:52 ` [PATCH 4/5] staging: exfat: add boot region verification Tetsuhiro Kohada
@ 2020-03-11 10:52 ` Tetsuhiro Kohada
2020-03-11 12:05 ` [PATCH 1/5] staging: exfat: conform 'pbr_sector_t' definition to exFAT specification Greg Kroah-Hartman
4 siblings, 0 replies; 6+ messages in thread
From: Tetsuhiro Kohada @ 2020-03-11 10:52 UTC (permalink / raw)
To: Kohada.Tetsuhiro
Cc: Mori.Takahiro, motai.hirotaka, Valdis Kletnieks,
Greg Kroah-Hartman, linux-fsdevel, devel, linux-kernel
- 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@ab.MitsubishiElectric.co.jp>
Signed-off-by: Tetsuhiro Kohada <Kohada.Tetsuhiro@dc.MitsubishiElectric.co.jp>
---
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
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 1/5] staging: exfat: conform 'pbr_sector_t' definition to exFAT specification
2020-03-11 10:52 [PATCH 1/5] staging: exfat: conform 'pbr_sector_t' definition to exFAT specification Tetsuhiro Kohada
` (3 preceding siblings ...)
2020-03-11 10:52 ` [PATCH 5/5] staging: exfat: standardize checksum calculation Tetsuhiro Kohada
@ 2020-03-11 12:05 ` Greg Kroah-Hartman
4 siblings, 0 replies; 6+ messages in thread
From: Greg Kroah-Hartman @ 2020-03-11 12:05 UTC (permalink / raw)
To: Tetsuhiro Kohada
Cc: devel, Valdis Kletnieks, motai.hirotaka, linux-kernel,
Mori.Takahiro, linux-fsdevel
On Wed, Mar 11, 2020 at 07:52:41PM +0900, Tetsuhiro Kohada wrote:
> Redefine 'pbr_sector_t' as 'boot_sector_t' to comply with exFAT specification.
> - Redefine 'pbr_sector_t' as 'boot_sector_t'.
> - Rename variable names including 'pbr'.
> - Replace GET**()/SET**() macro with cpu_to_le**()/le**_ to_cpu().
> - Remove fs_info_t.PBR_sector (always 0).
> - Remove unused definitions.
>
> Reviewed-by: Takahiro Mori <Mori.Takahiro@ab.MitsubishiElectric.co.jp>
> Signed-off-by: Tetsuhiro Kohada <Kohada.Tetsuhiro@dc.MitsubishiElectric.co.jp>
> ---
> drivers/staging/exfat/exfat.h | 139 +++++++---------------------
> drivers/staging/exfat/exfat_core.c | 62 ++++++-------
> drivers/staging/exfat/exfat_super.c | 14 ++-
> 3 files changed, 65 insertions(+), 150 deletions(-)
The drivers/staging/exfat/ tree is now gone from my staging-next branch
as there is a "real" version of exfat now in linux-next from the vfs
tree.
I suggest you start working on the fs/extfat/ code.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 6+ messages in thread