2019-10-23 12:02:13

by Valdis Klētnieks

[permalink] [raw]
Subject: [PATCH 0/8] staging: exfat: Code cleanups

Two main goals here - remove the code to mount FAT and VFAT filesystes,
and make a lot of functions static to reduce namespace pollution.

Valdis Kletnieks (8):
staging: exfat: Clean up namespace pollution, part 1
staging: exfat: Remove FAT/VFAT mount support, part 1
staging: exfat: Remove FAT/VFAT mount support, part 2
staging: exfat: Cleanup static entries in exfat.h
staging: exfat: Clean up static definitions in exfat_cache.c
staging: exfat: More static cleanups for exfat_core.c
staging: exfat: Finished code movement for static cleanups in exfat_core.c
staging: exfat: Update TODO

drivers/staging/exfat/Kconfig | 9 -
drivers/staging/exfat/TODO | 20 +-
drivers/staging/exfat/exfat.h | 122 +-
drivers/staging/exfat/exfat_cache.c | 94 +-
drivers/staging/exfat/exfat_core.c | 2162 ++++++++-------------------
drivers/staging/exfat/exfat_super.c | 8 +-
6 files changed, 690 insertions(+), 1725 deletions(-)

--
2.23.0


2019-10-23 12:17:17

by Valdis Klētnieks

[permalink] [raw]
Subject: [PATCH 6/8] staging: exfat: More static cleanups for exfat_core.c

Move static function bodies before first use, remove the definition in exfat.h

Signed-off-by: Valdis Kletnieks <[email protected]>
---
drivers/staging/exfat/exfat.h | 6 -
drivers/staging/exfat/exfat_core.c | 500 ++++++++++++++---------------
2 files changed, 250 insertions(+), 256 deletions(-)

diff --git a/drivers/staging/exfat/exfat.h b/drivers/staging/exfat/exfat.h
index 654a0c46c1a0..b93df526355b 100644
--- a/drivers/staging/exfat/exfat.h
+++ b/drivers/staging/exfat/exfat.h
@@ -786,10 +786,6 @@ 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);
-static s32 set_alloc_bitmap(struct super_block *sb, u32 clu);
-static s32 clr_alloc_bitmap(struct super_block *sb, u32 clu);
-static u32 test_alloc_bitmap(struct super_block *sb, u32 clu);
-static void sync_alloc_bitmap(struct super_block *sb);

/* upcase table management functions */
s32 load_upcase_table(struct super_block *sb);
@@ -812,8 +808,6 @@ void release_entry_set(struct entry_set_cache_t *es);
static s32 write_whole_entry_set(struct super_block *sb, struct entry_set_cache_t *es);
s32 count_dos_name_entries(struct super_block *sb, struct chain_t *p_dir,
u32 type);
-static void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir,
- s32 entry);
void update_dir_checksum_with_entry_set(struct super_block *sb,
struct entry_set_cache_t *es);
bool is_dir_empty(struct super_block *sb, struct chain_t *p_dir);
diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c
index dd69a9a6dddc..1a49da231946 100644
--- a/drivers/staging/exfat/exfat_core.c
+++ b/drivers/staging/exfat/exfat_core.c
@@ -132,6 +132,199 @@ static void fs_error(struct super_block *sb)
}
}

+/*
+ * Allocation Bitmap Management Functions
+ */
+
+s32 load_alloc_bitmap(struct super_block *sb)
+{
+ int i, j, ret;
+ u32 map_size;
+ u32 type;
+ sector_t sector;
+ struct chain_t clu;
+ struct bmap_dentry_t *ep;
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+ struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
+
+ clu.dir = p_fs->root_dir;
+ clu.flags = 0x01;
+
+ while (clu.dir != CLUSTER_32(~0)) {
+ if (p_fs->dev_ejected)
+ break;
+
+ for (i = 0; i < p_fs->dentries_per_clu; i++) {
+ ep = (struct bmap_dentry_t *)get_entry_in_dir(sb, &clu,
+ i, NULL);
+ if (!ep)
+ return FFS_MEDIAERR;
+
+ type = p_fs->fs_func->get_entry_type((struct dentry_t *)ep);
+
+ if (type == TYPE_UNUSED)
+ break;
+ if (type != TYPE_BITMAP)
+ continue;
+
+ if (ep->flags == 0x0) {
+ p_fs->map_clu = GET32_A(ep->start_clu);
+ map_size = (u32)GET64_A(ep->size);
+
+ p_fs->map_sectors = ((map_size - 1) >> p_bd->sector_size_bits) + 1;
+
+ p_fs->vol_amap = kmalloc_array(p_fs->map_sectors,
+ sizeof(struct buffer_head *),
+ GFP_KERNEL);
+ if (!p_fs->vol_amap)
+ return FFS_MEMORYERR;
+
+ sector = START_SECTOR(p_fs->map_clu);
+
+ for (j = 0; j < p_fs->map_sectors; j++) {
+ p_fs->vol_amap[j] = NULL;
+ ret = sector_read(sb, sector + j, &(p_fs->vol_amap[j]), 1);
+ if (ret != FFS_SUCCESS) {
+ /* release all buffers and free vol_amap */
+ i = 0;
+ while (i < j)
+ brelse(p_fs->vol_amap[i++]);
+
+ kfree(p_fs->vol_amap);
+ p_fs->vol_amap = NULL;
+ return ret;
+ }
+ }
+
+ p_fs->pbr_bh = NULL;
+ return FFS_SUCCESS;
+ }
+ }
+
+ if (FAT_read(sb, clu.dir, &clu.dir) != 0)
+ return FFS_MEDIAERR;
+ }
+
+ return FFS_FORMATERR;
+}
+
+void free_alloc_bitmap(struct super_block *sb)
+{
+ int i;
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ brelse(p_fs->pbr_bh);
+
+ for (i = 0; i < p_fs->map_sectors; i++)
+ __brelse(p_fs->vol_amap[i]);
+
+ kfree(p_fs->vol_amap);
+ p_fs->vol_amap = NULL;
+}
+
+static s32 set_alloc_bitmap(struct super_block *sb, u32 clu)
+{
+ int i, b;
+ sector_t sector;
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+ struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
+
+ i = clu >> (p_bd->sector_size_bits + 3);
+ b = clu & ((p_bd->sector_size << 3) - 1);
+
+ sector = START_SECTOR(p_fs->map_clu) + i;
+
+ exfat_bitmap_set((u8 *)p_fs->vol_amap[i]->b_data, b);
+
+ return sector_write(sb, sector, p_fs->vol_amap[i], 0);
+}
+
+static s32 clr_alloc_bitmap(struct super_block *sb, u32 clu)
+{
+ int i, b;
+ sector_t sector;
+#ifdef CONFIG_EXFAT_DISCARD
+ struct exfat_sb_info *sbi = EXFAT_SB(sb);
+ struct exfat_mount_options *opts = &sbi->options;
+ int ret;
+#endif /* CONFIG_EXFAT_DISCARD */
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+ struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
+
+ i = clu >> (p_bd->sector_size_bits + 3);
+ b = clu & ((p_bd->sector_size << 3) - 1);
+
+ sector = START_SECTOR(p_fs->map_clu) + i;
+
+ exfat_bitmap_clear((u8 *)p_fs->vol_amap[i]->b_data, b);
+
+ return sector_write(sb, sector, p_fs->vol_amap[i], 0);
+
+#ifdef CONFIG_EXFAT_DISCARD
+ if (opts->discard) {
+ ret = sb_issue_discard(sb, START_SECTOR(clu),
+ (1 << p_fs->sectors_per_clu_bits),
+ GFP_NOFS, 0);
+ if (ret == -EOPNOTSUPP) {
+ pr_warn("discard not supported by device, disabling");
+ opts->discard = 0;
+ }
+ }
+#endif /* CONFIG_EXFAT_DISCARD */
+}
+
+static u32 test_alloc_bitmap(struct super_block *sb, u32 clu)
+{
+ int i, map_i, map_b;
+ u32 clu_base, clu_free;
+ u8 k, clu_mask;
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+ struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
+
+ clu_base = (clu & ~(0x7)) + 2;
+ clu_mask = (1 << (clu - clu_base + 2)) - 1;
+
+ map_i = clu >> (p_bd->sector_size_bits + 3);
+ map_b = (clu >> 3) & p_bd->sector_size_mask;
+
+ for (i = 2; i < p_fs->num_clusters; i += 8) {
+ k = *(((u8 *)p_fs->vol_amap[map_i]->b_data) + map_b);
+ if (clu_mask > 0) {
+ k |= clu_mask;
+ clu_mask = 0;
+ }
+ if (k < 0xFF) {
+ clu_free = clu_base + free_bit[k];
+ if (clu_free < p_fs->num_clusters)
+ return clu_free;
+ }
+ clu_base += 8;
+
+ if (((++map_b) >= p_bd->sector_size) ||
+ (clu_base >= p_fs->num_clusters)) {
+ if ((++map_i) >= p_fs->map_sectors) {
+ clu_base = 2;
+ map_i = 0;
+ }
+ map_b = 0;
+ }
+ }
+
+ return CLUSTER_32(~0);
+}
+
+static void sync_alloc_bitmap(struct super_block *sb)
+{
+ int i;
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ if (!p_fs->vol_amap)
+ return;
+
+ for (i = 0; i < p_fs->map_sectors; i++)
+ sync_dirty_buffer(p_fs->vol_amap[i]);
+}
+
/*
* Cluster Management Functions
*/
@@ -388,199 +581,6 @@ void exfat_chain_cont_cluster(struct super_block *sb, u32 chain, s32 len)
FAT_write(sb, chain, CLUSTER_32(~0));
}

-/*
- * Allocation Bitmap Management Functions
- */
-
-s32 load_alloc_bitmap(struct super_block *sb)
-{
- int i, j, ret;
- u32 map_size;
- u32 type;
- sector_t sector;
- struct chain_t clu;
- struct bmap_dentry_t *ep;
- struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
- struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-
- clu.dir = p_fs->root_dir;
- clu.flags = 0x01;
-
- while (clu.dir != CLUSTER_32(~0)) {
- if (p_fs->dev_ejected)
- break;
-
- for (i = 0; i < p_fs->dentries_per_clu; i++) {
- ep = (struct bmap_dentry_t *)get_entry_in_dir(sb, &clu,
- i, NULL);
- if (!ep)
- return FFS_MEDIAERR;
-
- type = p_fs->fs_func->get_entry_type((struct dentry_t *)ep);
-
- if (type == TYPE_UNUSED)
- break;
- if (type != TYPE_BITMAP)
- continue;
-
- if (ep->flags == 0x0) {
- p_fs->map_clu = GET32_A(ep->start_clu);
- map_size = (u32)GET64_A(ep->size);
-
- p_fs->map_sectors = ((map_size - 1) >> p_bd->sector_size_bits) + 1;
-
- p_fs->vol_amap = kmalloc_array(p_fs->map_sectors,
- sizeof(struct buffer_head *),
- GFP_KERNEL);
- if (!p_fs->vol_amap)
- return FFS_MEMORYERR;
-
- sector = START_SECTOR(p_fs->map_clu);
-
- for (j = 0; j < p_fs->map_sectors; j++) {
- p_fs->vol_amap[j] = NULL;
- ret = sector_read(sb, sector + j, &(p_fs->vol_amap[j]), 1);
- if (ret != FFS_SUCCESS) {
- /* release all buffers and free vol_amap */
- i = 0;
- while (i < j)
- brelse(p_fs->vol_amap[i++]);
-
- kfree(p_fs->vol_amap);
- p_fs->vol_amap = NULL;
- return ret;
- }
- }
-
- p_fs->pbr_bh = NULL;
- return FFS_SUCCESS;
- }
- }
-
- if (FAT_read(sb, clu.dir, &clu.dir) != 0)
- return FFS_MEDIAERR;
- }
-
- return FFS_FORMATERR;
-}
-
-void free_alloc_bitmap(struct super_block *sb)
-{
- int i;
- struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-
- brelse(p_fs->pbr_bh);
-
- for (i = 0; i < p_fs->map_sectors; i++)
- __brelse(p_fs->vol_amap[i]);
-
- kfree(p_fs->vol_amap);
- p_fs->vol_amap = NULL;
-}
-
-static s32 set_alloc_bitmap(struct super_block *sb, u32 clu)
-{
- int i, b;
- sector_t sector;
- struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
- struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-
- i = clu >> (p_bd->sector_size_bits + 3);
- b = clu & ((p_bd->sector_size << 3) - 1);
-
- sector = START_SECTOR(p_fs->map_clu) + i;
-
- exfat_bitmap_set((u8 *)p_fs->vol_amap[i]->b_data, b);
-
- return sector_write(sb, sector, p_fs->vol_amap[i], 0);
-}
-
-static s32 clr_alloc_bitmap(struct super_block *sb, u32 clu)
-{
- int i, b;
- sector_t sector;
-#ifdef CONFIG_EXFAT_DISCARD
- struct exfat_sb_info *sbi = EXFAT_SB(sb);
- struct exfat_mount_options *opts = &sbi->options;
- int ret;
-#endif /* CONFIG_EXFAT_DISCARD */
- struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
- struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-
- i = clu >> (p_bd->sector_size_bits + 3);
- b = clu & ((p_bd->sector_size << 3) - 1);
-
- sector = START_SECTOR(p_fs->map_clu) + i;
-
- exfat_bitmap_clear((u8 *)p_fs->vol_amap[i]->b_data, b);
-
- return sector_write(sb, sector, p_fs->vol_amap[i], 0);
-
-#ifdef CONFIG_EXFAT_DISCARD
- if (opts->discard) {
- ret = sb_issue_discard(sb, START_SECTOR(clu),
- (1 << p_fs->sectors_per_clu_bits),
- GFP_NOFS, 0);
- if (ret == -EOPNOTSUPP) {
- pr_warn("discard not supported by device, disabling");
- opts->discard = 0;
- }
- }
-#endif /* CONFIG_EXFAT_DISCARD */
-}
-
-static u32 test_alloc_bitmap(struct super_block *sb, u32 clu)
-{
- int i, map_i, map_b;
- u32 clu_base, clu_free;
- u8 k, clu_mask;
- struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
- struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-
- clu_base = (clu & ~(0x7)) + 2;
- clu_mask = (1 << (clu - clu_base + 2)) - 1;
-
- map_i = clu >> (p_bd->sector_size_bits + 3);
- map_b = (clu >> 3) & p_bd->sector_size_mask;
-
- for (i = 2; i < p_fs->num_clusters; i += 8) {
- k = *(((u8 *)p_fs->vol_amap[map_i]->b_data) + map_b);
- if (clu_mask > 0) {
- k |= clu_mask;
- clu_mask = 0;
- }
- if (k < 0xFF) {
- clu_free = clu_base + free_bit[k];
- if (clu_free < p_fs->num_clusters)
- return clu_free;
- }
- clu_base += 8;
-
- if (((++map_b) >= p_bd->sector_size) ||
- (clu_base >= p_fs->num_clusters)) {
- if ((++map_i) >= p_fs->map_sectors) {
- clu_base = 2;
- map_i = 0;
- }
- map_b = 0;
- }
- }
-
- return CLUSTER_32(~0);
-}
-
-static void sync_alloc_bitmap(struct super_block *sb)
-{
- int i;
- struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-
- if (!p_fs->vol_amap)
- return;
-
- for (i = 0; i < p_fs->map_sectors; i++)
- sync_dirty_buffer(p_fs->vol_amap[i]);
-}
-
/*
* Upcase table Management Functions
*/
@@ -791,6 +791,63 @@ void free_upcase_table(struct super_block *sb)
p_fs->vol_utbl = NULL;
}

+static void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir,
+ s32 entry)
+{
+ int i, num_entries;
+ sector_t sector;
+ u16 chksum;
+ struct file_dentry_t *file_ep;
+ struct dentry_t *ep;
+
+ file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry,
+ &sector);
+ if (!file_ep)
+ return;
+
+ 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);
+
+ for (i = 1; i < num_entries; i++) {
+ ep = get_entry_in_dir(sb, p_dir, entry + i, NULL);
+ if (!ep) {
+ buf_unlock(sb, sector);
+ return;
+ }
+
+ chksum = calc_checksum_2byte((void *)ep, DENTRY_SIZE, chksum,
+ CS_DEFAULT);
+ }
+
+ SET16_A(file_ep->checksum, chksum);
+ buf_modify(sb, sector);
+ buf_unlock(sb, sector);
+}
+
+void update_dir_checksum_with_entry_set(struct super_block *sb,
+ struct entry_set_cache_t *es)
+{
+ struct dentry_t *ep;
+ u16 chksum = 0;
+ s32 chksum_type = CS_DIR_ENTRY, i;
+
+ 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);
+ ep++;
+ chksum_type = CS_DEFAULT;
+ }
+
+ ep = (struct dentry_t *)&(es->__buf);
+ SET16_A(((struct file_dentry_t *)ep)->checksum, chksum);
+ write_whole_entry_set(sb, es);
+}
+
/*
* Directory Entry Management Functions
*/
@@ -1114,63 +1171,6 @@ static void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir
}
}

-static void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir,
- s32 entry)
-{
- int i, num_entries;
- sector_t sector;
- u16 chksum;
- struct file_dentry_t *file_ep;
- struct dentry_t *ep;
-
- file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry,
- &sector);
- if (!file_ep)
- return;
-
- 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);
-
- for (i = 1; i < num_entries; i++) {
- ep = get_entry_in_dir(sb, p_dir, entry + i, NULL);
- if (!ep) {
- buf_unlock(sb, sector);
- return;
- }
-
- chksum = calc_checksum_2byte((void *)ep, DENTRY_SIZE, chksum,
- CS_DEFAULT);
- }
-
- SET16_A(file_ep->checksum, chksum);
- buf_modify(sb, sector);
- buf_unlock(sb, sector);
-}
-
-void update_dir_checksum_with_entry_set(struct super_block *sb,
- struct entry_set_cache_t *es)
-{
- struct dentry_t *ep;
- u16 chksum = 0;
- s32 chksum_type = CS_DIR_ENTRY, i;
-
- 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);
- ep++;
- chksum_type = CS_DEFAULT;
- }
-
- ep = (struct dentry_t *)&(es->__buf);
- SET16_A(((struct file_dentry_t *)ep)->checksum, chksum);
- write_whole_entry_set(sb, es);
-}
-
static s32 _walk_fat_chain(struct super_block *sb, struct chain_t *p_dir,
s32 byte_offset, u32 *clu)
{
--
2.23.0

2019-10-23 12:17:17

by Valdis Klētnieks

[permalink] [raw]
Subject: [PATCH 7/8] staging: exfat: Finished code movement for static cleanups in exfat_core.c

Move static function bodies before first use, remove the definition in exfat.h

Signed-off-by: Valdis Kletnieks <[email protected]>
---
drivers/staging/exfat/exfat.h | 10 -
drivers/staging/exfat/exfat_core.c | 661 ++++++++++++++---------------
2 files changed, 330 insertions(+), 341 deletions(-)

diff --git a/drivers/staging/exfat/exfat.h b/drivers/staging/exfat/exfat.h
index b93df526355b..8738e41dd5a5 100644
--- a/drivers/staging/exfat/exfat.h
+++ b/drivers/staging/exfat/exfat.h
@@ -793,10 +793,6 @@ void free_upcase_table(struct super_block *sb);

/* dir entry management functions */
struct timestamp_t *tm_current(struct timestamp_t *tm);
-static void init_file_entry(struct file_dentry_t *ep, u32 type);
-static void init_strm_entry(struct strm_dentry_t *ep, u8 flags, u32 start_clu,
- u64 size);
-static void init_name_entry(struct name_dentry_t *ep, u16 *uniname);

struct dentry_t *get_entry_in_dir(struct super_block *sb, struct chain_t *p_dir,
s32 entry, sector_t *sector);
@@ -805,7 +801,6 @@ struct entry_set_cache_t *get_entry_set_in_dir(struct super_block *sb,
u32 type,
struct dentry_t **file_ep);
void release_entry_set(struct entry_set_cache_t *es);
-static s32 write_whole_entry_set(struct super_block *sb, struct entry_set_cache_t *es);
s32 count_dos_name_entries(struct super_block *sb, struct chain_t *p_dir,
u32 type);
void update_dir_checksum_with_entry_set(struct super_block *sb,
@@ -819,11 +814,6 @@ s32 get_num_entries_and_dos_name(struct super_block *sb, struct chain_t *p_dir,
void get_uni_name_from_dos_entry(struct super_block *sb,
struct dos_dentry_t *ep,
struct uni_name_t *p_uniname, u8 mode);
-static s32 extract_uni_name_from_name_entry(struct name_dentry_t *ep, u16 *uniname,
- s32 order);
-static s32 fat_generate_dos_name(struct super_block *sb, struct chain_t *p_dir,
- struct dos_name_t *p_dosname);
-static void fat_attach_count_to_dos_name(u8 *dosname, s32 count);
u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type);

/* name resolution functions */
diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c
index 1a49da231946..7332e69fcbcd 100644
--- a/drivers/staging/exfat/exfat_core.c
+++ b/drivers/staging/exfat/exfat_core.c
@@ -791,6 +791,168 @@ void free_upcase_table(struct super_block *sb)
p_fs->vol_utbl = NULL;
}

+static s32 __write_partial_entries_in_entry_set(struct super_block *sb,
+ struct entry_set_cache_t *es,
+ sector_t sec, s32 off, u32 count)
+{
+ s32 num_entries, buf_off = (off - es->offset);
+ u32 remaining_byte_in_sector, copy_entries;
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+ struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
+ u32 clu;
+ u8 *buf, *esbuf = (u8 *)&(es->__buf);
+
+ pr_debug("%s entered es %p sec %llu off %d count %d\n",
+ __func__, es, (unsigned long long)sec, off, count);
+ num_entries = count;
+
+ while (num_entries) {
+ /* white per sector base */
+ remaining_byte_in_sector = (1 << p_bd->sector_size_bits) - off;
+ copy_entries = min_t(s32,
+ remaining_byte_in_sector >> DENTRY_SIZE_BITS,
+ num_entries);
+ buf = buf_getblk(sb, sec);
+ if (!buf)
+ goto err_out;
+ pr_debug("es->buf %p buf_off %u\n", esbuf, buf_off);
+ pr_debug("copying %d entries from %p to sector %llu\n",
+ copy_entries, (esbuf + buf_off),
+ (unsigned long long)sec);
+ memcpy(buf + off, esbuf + buf_off,
+ copy_entries << DENTRY_SIZE_BITS);
+ buf_modify(sb, sec);
+ num_entries -= copy_entries;
+
+ if (num_entries) {
+ /* get next sector */
+ if (IS_LAST_SECTOR_IN_CLUSTER(sec)) {
+ clu = GET_CLUSTER_FROM_SECTOR(sec);
+ if (es->alloc_flag == 0x03) {
+ clu++;
+ } else {
+ if (FAT_read(sb, clu, &clu) == -1)
+ goto err_out;
+ }
+ sec = START_SECTOR(clu);
+ } else {
+ sec++;
+ }
+ off = 0;
+ buf_off += copy_entries << DENTRY_SIZE_BITS;
+ }
+ }
+
+ pr_debug("%s exited successfully\n", __func__);
+ return FFS_SUCCESS;
+err_out:
+ pr_debug("%s failed\n", __func__);
+ return FFS_ERROR;
+}
+
+/* write back all entries in entry set */
+static s32 write_whole_entry_set(struct super_block *sb, struct entry_set_cache_t *es)
+{
+ return __write_partial_entries_in_entry_set(sb, es, es->sector,
+ es->offset,
+ es->num_entries);
+}
+
+/* search EMPTY CONTINUOUS "num_entries" entries */
+static s32 search_deleted_or_unused_entry(struct super_block *sb,
+ struct chain_t *p_dir, s32 num_entries)
+{
+ int i, dentry, num_empty = 0;
+ s32 dentries_per_clu;
+ u32 type;
+ struct chain_t clu;
+ struct dentry_t *ep;
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
+ dentries_per_clu = p_fs->dentries_in_root;
+ else
+ dentries_per_clu = p_fs->dentries_per_clu;
+
+ if (p_fs->hint_uentry.dir == p_dir->dir) {
+ if (p_fs->hint_uentry.entry == -1)
+ return -1;
+
+ clu.dir = p_fs->hint_uentry.clu.dir;
+ clu.size = p_fs->hint_uentry.clu.size;
+ clu.flags = p_fs->hint_uentry.clu.flags;
+
+ dentry = p_fs->hint_uentry.entry;
+ } else {
+ p_fs->hint_uentry.entry = -1;
+
+ clu.dir = p_dir->dir;
+ clu.size = p_dir->size;
+ clu.flags = p_dir->flags;
+
+ dentry = 0;
+ }
+
+ while (clu.dir != CLUSTER_32(~0)) {
+ if (p_fs->dev_ejected)
+ break;
+
+ if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
+ i = dentry % dentries_per_clu;
+ else
+ i = dentry & (dentries_per_clu - 1);
+
+ for (; i < dentries_per_clu; i++, dentry++) {
+ ep = get_entry_in_dir(sb, &clu, i, NULL);
+ if (!ep)
+ return -1;
+
+ type = p_fs->fs_func->get_entry_type(ep);
+
+ if (type == TYPE_UNUSED) {
+ num_empty++;
+ if (p_fs->hint_uentry.entry == -1) {
+ p_fs->hint_uentry.dir = p_dir->dir;
+ p_fs->hint_uentry.entry = dentry;
+
+ p_fs->hint_uentry.clu.dir = clu.dir;
+ p_fs->hint_uentry.clu.size = clu.size;
+ p_fs->hint_uentry.clu.flags = clu.flags;
+ }
+ } else if (type == TYPE_DELETED) {
+ num_empty++;
+ } else {
+ num_empty = 0;
+ }
+
+ if (num_empty >= num_entries) {
+ p_fs->hint_uentry.dir = CLUSTER_32(~0);
+ p_fs->hint_uentry.entry = -1;
+
+ if (p_fs->vol_type == EXFAT)
+ return dentry - (num_entries - 1);
+ else
+ return dentry;
+ }
+ }
+
+ if (p_dir->dir == CLUSTER_32(0))
+ break; /* FAT16 root_dir */
+
+ if (clu.flags == 0x03) {
+ if ((--clu.size) > 0)
+ clu.dir++;
+ else
+ clu.dir = CLUSTER_32(~0);
+ } else {
+ if (FAT_read(sb, clu.dir, &clu.dir) != 0)
+ return -1;
+ }
+ }
+
+ return -1;
+}
+
static void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir,
s32 entry)
{
@@ -1038,6 +1200,45 @@ static void exfat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *t
}
}

+static void init_file_entry(struct file_dentry_t *ep, u32 type)
+{
+ struct timestamp_t tm, *tp;
+
+ exfat_set_entry_type((struct dentry_t *)ep, type);
+
+ tp = tm_current(&tm);
+ exfat_set_entry_time((struct dentry_t *)ep, tp, TM_CREATE);
+ exfat_set_entry_time((struct dentry_t *)ep, tp, TM_MODIFY);
+ exfat_set_entry_time((struct dentry_t *)ep, tp, TM_ACCESS);
+ ep->create_time_ms = 0;
+ ep->modify_time_ms = 0;
+ ep->access_time_ms = 0;
+}
+
+static void init_strm_entry(struct strm_dentry_t *ep, u8 flags, u32 start_clu, u64 size)
+{
+ exfat_set_entry_type((struct dentry_t *)ep, TYPE_STREAM);
+ ep->flags = flags;
+ SET32_A(ep->start_clu, start_clu);
+ SET64_A(ep->valid_size, size);
+ SET64_A(ep->size, size);
+}
+
+static void init_name_entry(struct name_dentry_t *ep, u16 *uniname)
+{
+ int i;
+
+ exfat_set_entry_type((struct dentry_t *)ep, TYPE_EXTEND);
+ ep->flags = 0x0;
+
+ for (i = 0; i < 30; i++, i++) {
+ SET16_A(ep->unicode_0_14 + i, *uniname);
+ if (*uniname == 0x0)
+ break;
+ uniname++;
+ }
+}
+
static s32 exfat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir,
s32 entry, u32 type, u32 start_clu, u64 size)
{
@@ -1114,45 +1315,6 @@ static s32 exfat_init_ext_entry(struct super_block *sb, struct chain_t *p_dir,
return FFS_SUCCESS;
}

-static void init_file_entry(struct file_dentry_t *ep, u32 type)
-{
- struct timestamp_t tm, *tp;
-
- exfat_set_entry_type((struct dentry_t *)ep, type);
-
- tp = tm_current(&tm);
- exfat_set_entry_time((struct dentry_t *)ep, tp, TM_CREATE);
- exfat_set_entry_time((struct dentry_t *)ep, tp, TM_MODIFY);
- exfat_set_entry_time((struct dentry_t *)ep, tp, TM_ACCESS);
- ep->create_time_ms = 0;
- ep->modify_time_ms = 0;
- ep->access_time_ms = 0;
-}
-
-static void init_strm_entry(struct strm_dentry_t *ep, u8 flags, u32 start_clu, u64 size)
-{
- exfat_set_entry_type((struct dentry_t *)ep, TYPE_STREAM);
- ep->flags = flags;
- SET32_A(ep->start_clu, start_clu);
- SET64_A(ep->valid_size, size);
- SET64_A(ep->size, size);
-}
-
-static void init_name_entry(struct name_dentry_t *ep, u16 *uniname)
-{
- int i;
-
- exfat_set_entry_type((struct dentry_t *)ep, TYPE_EXTEND);
- ep->flags = 0x0;
-
- for (i = 0; i < 30; i++, i++) {
- SET16_A(ep->unicode_0_14 + i, *uniname);
- if (*uniname == 0x0)
- break;
- uniname++;
- }
-}
-
static void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir,
s32 entry, s32 order, s32 num_entries)
{
@@ -1432,177 +1594,15 @@ void release_entry_set(struct entry_set_cache_t *es)
kfree(es);
}

-static s32 __write_partial_entries_in_entry_set(struct super_block *sb,
- struct entry_set_cache_t *es,
- sector_t sec, s32 off, u32 count)
+static s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir, s32 num_entries)
{
- s32 num_entries, buf_off = (off - es->offset);
- u32 remaining_byte_in_sector, copy_entries;
- struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
- struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
- u32 clu;
- u8 *buf, *esbuf = (u8 *)&(es->__buf);
-
- pr_debug("%s entered es %p sec %llu off %d count %d\n",
- __func__, es, (unsigned long long)sec, off, count);
- num_entries = count;
-
- while (num_entries) {
- /* white per sector base */
- remaining_byte_in_sector = (1 << p_bd->sector_size_bits) - off;
- copy_entries = min_t(s32,
- remaining_byte_in_sector >> DENTRY_SIZE_BITS,
- num_entries);
- buf = buf_getblk(sb, sec);
- if (!buf)
- goto err_out;
- pr_debug("es->buf %p buf_off %u\n", esbuf, buf_off);
- pr_debug("copying %d entries from %p to sector %llu\n",
- copy_entries, (esbuf + buf_off),
- (unsigned long long)sec);
- memcpy(buf + off, esbuf + buf_off,
- copy_entries << DENTRY_SIZE_BITS);
- buf_modify(sb, sec);
- num_entries -= copy_entries;
-
- if (num_entries) {
- /* get next sector */
- if (IS_LAST_SECTOR_IN_CLUSTER(sec)) {
- clu = GET_CLUSTER_FROM_SECTOR(sec);
- if (es->alloc_flag == 0x03) {
- clu++;
- } else {
- if (FAT_read(sb, clu, &clu) == -1)
- goto err_out;
- }
- sec = START_SECTOR(clu);
- } else {
- sec++;
- }
- off = 0;
- buf_off += copy_entries << DENTRY_SIZE_BITS;
- }
- }
-
- pr_debug("%s exited successfully\n", __func__);
- return FFS_SUCCESS;
-err_out:
- pr_debug("%s failed\n", __func__);
- return FFS_ERROR;
-}
-
-/* write back all entries in entry set */
-static s32 write_whole_entry_set(struct super_block *sb, struct entry_set_cache_t *es)
-{
- return __write_partial_entries_in_entry_set(sb, es, es->sector,
- es->offset,
- es->num_entries);
-}
-
-/* search EMPTY CONTINUOUS "num_entries" entries */
-static s32 search_deleted_or_unused_entry(struct super_block *sb,
- struct chain_t *p_dir, s32 num_entries)
-{
- int i, dentry, num_empty = 0;
- s32 dentries_per_clu;
- u32 type;
- struct chain_t clu;
- struct dentry_t *ep;
- struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-
- if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
- dentries_per_clu = p_fs->dentries_in_root;
- else
- dentries_per_clu = p_fs->dentries_per_clu;
-
- if (p_fs->hint_uentry.dir == p_dir->dir) {
- if (p_fs->hint_uentry.entry == -1)
- return -1;
-
- clu.dir = p_fs->hint_uentry.clu.dir;
- clu.size = p_fs->hint_uentry.clu.size;
- clu.flags = p_fs->hint_uentry.clu.flags;
-
- dentry = p_fs->hint_uentry.entry;
- } else {
- p_fs->hint_uentry.entry = -1;
-
- clu.dir = p_dir->dir;
- clu.size = p_dir->size;
- clu.flags = p_dir->flags;
-
- dentry = 0;
- }
-
- while (clu.dir != CLUSTER_32(~0)) {
- if (p_fs->dev_ejected)
- break;
-
- if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
- i = dentry % dentries_per_clu;
- else
- i = dentry & (dentries_per_clu - 1);
-
- for (; i < dentries_per_clu; i++, dentry++) {
- ep = get_entry_in_dir(sb, &clu, i, NULL);
- if (!ep)
- return -1;
-
- type = p_fs->fs_func->get_entry_type(ep);
-
- if (type == TYPE_UNUSED) {
- num_empty++;
- if (p_fs->hint_uentry.entry == -1) {
- p_fs->hint_uentry.dir = p_dir->dir;
- p_fs->hint_uentry.entry = dentry;
-
- p_fs->hint_uentry.clu.dir = clu.dir;
- p_fs->hint_uentry.clu.size = clu.size;
- p_fs->hint_uentry.clu.flags = clu.flags;
- }
- } else if (type == TYPE_DELETED) {
- num_empty++;
- } else {
- num_empty = 0;
- }
-
- if (num_empty >= num_entries) {
- p_fs->hint_uentry.dir = CLUSTER_32(~0);
- p_fs->hint_uentry.entry = -1;
-
- if (p_fs->vol_type == EXFAT)
- return dentry - (num_entries - 1);
- else
- return dentry;
- }
- }
-
- if (p_dir->dir == CLUSTER_32(0))
- break; /* FAT16 root_dir */
-
- if (clu.flags == 0x03) {
- if ((--clu.size) > 0)
- clu.dir++;
- else
- clu.dir = CLUSTER_32(~0);
- } else {
- if (FAT_read(sb, clu.dir, &clu.dir) != 0)
- return -1;
- }
- }
-
- return -1;
-}
-
-static s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir, s32 num_entries)
-{
- s32 ret, dentry;
- u32 last_clu;
- sector_t sector;
- u64 size = 0;
- struct chain_t clu;
- struct dentry_t *ep = NULL;
- struct super_block *sb = inode->i_sb;
+ s32 ret, dentry;
+ u32 last_clu;
+ sector_t sector;
+ u64 size = 0;
+ struct chain_t clu;
+ struct dentry_t *ep = NULL;
+ struct super_block *sb = inode->i_sb;
struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
struct file_id_t *fid = &(EXFAT_I(inode)->fid);

@@ -1680,6 +1680,23 @@ static s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir, s32 num_
return dentry;
}

+static s32 extract_uni_name_from_name_entry(struct name_dentry_t *ep, u16 *uniname,
+ s32 order)
+{
+ int i, len = 0;
+
+ for (i = 0; i < 30; i += 2) {
+ *uniname = GET16_A(ep->unicode_0_14 + i);
+ if (*uniname == 0x0)
+ return len;
+ uniname++;
+ len++;
+ }
+
+ *uniname = 0x0;
+ return len;
+}
+
/* return values of exfat_find_dir_entry()
* >= 0 : return dir entiry position with the name in dir
* -1 : (root dir, ".") it is the root dir itself
@@ -1971,116 +1988,31 @@ bool is_dir_empty(struct super_block *sb, struct chain_t *p_dir)
/*
* Name Conversion Functions
*/
-
-/* input : dir, uni_name
- * output : num_of_entry, dos_name(format : aaaaaa~1.bbb)
- */
-s32 get_num_entries_and_dos_name(struct super_block *sb, struct chain_t *p_dir,
- struct uni_name_t *p_uniname, s32 *entries,
- struct dos_name_t *p_dosname)
-{
- s32 ret, num_entries;
- bool lossy = false;
- char **r;
- struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-
- num_entries = p_fs->fs_func->calc_num_entries(p_uniname);
- if (num_entries == 0)
- return FFS_INVALIDPATH;
-
- if (p_fs->vol_type != EXFAT) {
- nls_uniname_to_dosname(sb, p_dosname, p_uniname, &lossy);
-
- if (lossy) {
- ret = fat_generate_dos_name(sb, p_dir, p_dosname);
- if (ret)
- return ret;
- } else {
- for (r = reserved_names; *r; r++) {
- if (!strncmp((void *)p_dosname->name, *r, 8))
- return FFS_INVALIDPATH;
- }
-
- if (p_dosname->name_case != 0xFF)
- num_entries = 1;
- }
-
- if (num_entries > 1)
- p_dosname->name_case = 0x0;
- }
-
- *entries = num_entries;
-
- return FFS_SUCCESS;
-}
-
-void get_uni_name_from_dos_entry(struct super_block *sb,
- struct dos_dentry_t *ep,
- struct uni_name_t *p_uniname, u8 mode)
-{
- struct dos_name_t dos_name;
-
- if (mode == 0x0)
- dos_name.name_case = 0x0;
- else
- dos_name.name_case = ep->lcase;
-
- memcpy(dos_name.name, ep->name, DOS_NAME_LENGTH);
- nls_dosname_to_uniname(sb, p_uniname, &dos_name);
-}
-
-static void exfat_get_uni_name_from_ext_entry(struct super_block *sb,
- struct chain_t *p_dir, s32 entry,
- u16 *uniname)
+static void fat_attach_count_to_dos_name(u8 *dosname, s32 count)
{
- int i;
- struct dentry_t *ep;
- struct entry_set_cache_t *es;
- struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-
- es = get_entry_set_in_dir(sb, p_dir, entry, ES_ALL_ENTRIES, &ep);
- if (!es || es->num_entries < 3) {
- if (es)
- release_entry_set(es);
- return;
- }
+ int i, j, length;
+ char str_count[6];

- ep += 2;
+ snprintf(str_count, sizeof(str_count), "~%d", count);
+ length = strlen(str_count);

- /*
- * First entry : file entry
- * Second entry : stream-extension entry
- * Third entry : first file-name entry
- * So, the index of first file-name dentry should start from 2.
- */
- for (i = 2; i < es->num_entries; i++, ep++) {
- if (p_fs->fs_func->get_entry_type(ep) == TYPE_EXTEND)
- extract_uni_name_from_name_entry((struct name_dentry_t *)
- ep, uniname, i);
+ i = 0;
+ j = 0;
+ while (j <= (8 - length)) {
+ i = j;
+ if (dosname[j] == ' ')
+ break;
+ if (dosname[j] & 0x80)
+ j += 2;
else
- goto out;
- uniname += 15;
+ j++;
}

-out:
- release_entry_set(es);
-}
-
-static s32 extract_uni_name_from_name_entry(struct name_dentry_t *ep, u16 *uniname,
- s32 order)
-{
- int i, len = 0;
-
- for (i = 0; i < 30; i += 2) {
- *uniname = GET16_A(ep->unicode_0_14 + i);
- if (*uniname == 0x0)
- return len;
- uniname++;
- len++;
- }
+ for (j = 0; j < length; i++, j++)
+ dosname[i] = (u8)str_count[j];

- *uniname = 0x0;
- return len;
+ if (i == 7)
+ dosname[7] = ' ';
}

static s32 fat_generate_dos_name(struct super_block *sb, struct chain_t *p_dir,
@@ -2178,31 +2110,98 @@ static s32 fat_generate_dos_name(struct super_block *sb, struct chain_t *p_dir,
return FFS_SUCCESS;
}

-static void fat_attach_count_to_dos_name(u8 *dosname, s32 count)
+/* input : dir, uni_name
+ * output : num_of_entry, dos_name(format : aaaaaa~1.bbb)
+ */
+s32 get_num_entries_and_dos_name(struct super_block *sb, struct chain_t *p_dir,
+ struct uni_name_t *p_uniname, s32 *entries,
+ struct dos_name_t *p_dosname)
{
- int i, j, length;
- char str_count[6];
+ s32 ret, num_entries;
+ bool lossy = false;
+ char **r;
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);

- snprintf(str_count, sizeof(str_count), "~%d", count);
- length = strlen(str_count);
+ num_entries = p_fs->fs_func->calc_num_entries(p_uniname);
+ if (num_entries == 0)
+ return FFS_INVALIDPATH;

- i = 0;
- j = 0;
- while (j <= (8 - length)) {
- i = j;
- if (dosname[j] == ' ')
- break;
- if (dosname[j] & 0x80)
- j += 2;
- else
- j++;
+ if (p_fs->vol_type != EXFAT) {
+ nls_uniname_to_dosname(sb, p_dosname, p_uniname, &lossy);
+
+ if (lossy) {
+ ret = fat_generate_dos_name(sb, p_dir, p_dosname);
+ if (ret)
+ return ret;
+ } else {
+ for (r = reserved_names; *r; r++) {
+ if (!strncmp((void *)p_dosname->name, *r, 8))
+ return FFS_INVALIDPATH;
+ }
+
+ if (p_dosname->name_case != 0xFF)
+ num_entries = 1;
+ }
+
+ if (num_entries > 1)
+ p_dosname->name_case = 0x0;
}

- for (j = 0; j < length; i++, j++)
- dosname[i] = (u8)str_count[j];
+ *entries = num_entries;

- if (i == 7)
- dosname[7] = ' ';
+ return FFS_SUCCESS;
+}
+
+void get_uni_name_from_dos_entry(struct super_block *sb,
+ struct dos_dentry_t *ep,
+ struct uni_name_t *p_uniname, u8 mode)
+{
+ struct dos_name_t dos_name;
+
+ if (mode == 0x0)
+ dos_name.name_case = 0x0;
+ else
+ dos_name.name_case = ep->lcase;
+
+ memcpy(dos_name.name, ep->name, DOS_NAME_LENGTH);
+ nls_dosname_to_uniname(sb, p_uniname, &dos_name);
+}
+
+static void exfat_get_uni_name_from_ext_entry(struct super_block *sb,
+ struct chain_t *p_dir, s32 entry,
+ u16 *uniname)
+{
+ int i;
+ struct dentry_t *ep;
+ struct entry_set_cache_t *es;
+ struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
+
+ es = get_entry_set_in_dir(sb, p_dir, entry, ES_ALL_ENTRIES, &ep);
+ if (!es || es->num_entries < 3) {
+ if (es)
+ release_entry_set(es);
+ return;
+ }
+
+ ep += 2;
+
+ /*
+ * First entry : file entry
+ * Second entry : stream-extension entry
+ * Third entry : first file-name entry
+ * So, the index of first file-name dentry should start from 2.
+ */
+ for (i = 2; i < es->num_entries; i++, ep++) {
+ if (p_fs->fs_func->get_entry_type(ep) == TYPE_EXTEND)
+ extract_uni_name_from_name_entry((struct name_dentry_t *)
+ ep, uniname, i);
+ else
+ goto out;
+ uniname += 15;
+ }
+
+out:
+ release_entry_set(es);
}

static s32 exfat_calc_num_entries(struct uni_name_t *p_uniname)
--
2.23.0