* If the value of "clu" is 0, it means cluster 2 which is the first cluster of
* the cluster heap.
*/
-void exfat_clear_bitmap(struct inode *inode, unsigned int clu)
+void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync)
{
int i, b;
unsigned int ent_idx;
b = BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent_idx);
clear_bit_le(b, sbi->vol_amap[i]->b_data);
- exfat_update_bh(sbi->vol_amap[i], IS_DIRSYNC(inode));
+ exfat_update_bh(sbi->vol_amap[i], sync);
if (opts->discard) {
int ret_discard;
int exfat_load_bitmap(struct super_block *sb);
void exfat_free_bitmap(struct exfat_sb_info *sbi);
int exfat_set_bitmap(struct inode *inode, unsigned int clu);
-void exfat_clear_bitmap(struct inode *inode, unsigned int clu);
+void exfat_clear_bitmap(struct inode *inode, unsigned int clu, bool sync);
unsigned int exfat_find_free_bitmap(struct super_block *sb, unsigned int clu);
int exfat_count_used_clusters(struct super_block *sb, unsigned int *ret_count);
unsigned int clu;
struct super_block *sb = inode->i_sb;
struct exfat_sb_info *sbi = EXFAT_SB(sb);
+ int cur_cmap_i, next_cmap_i;
/* invalid cluster number */
if (p_chain->dir == EXFAT_FREE_CLUSTER ||
clu = p_chain->dir;
+ cur_cmap_i = next_cmap_i =
+ BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu));
+
if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
+ unsigned int last_cluster = p_chain->dir + p_chain->size - 1;
do {
- exfat_clear_bitmap(inode, clu);
- clu++;
+ bool sync = false;
+
+ if (clu < last_cluster)
+ next_cmap_i =
+ BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu+1));
+ /* flush bitmap only if index would be changed or for last cluster */
+ if (clu == last_cluster || cur_cmap_i != next_cmap_i) {
+ sync = true;
+ cur_cmap_i = next_cmap_i;
+ }
+
+ exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode)));
+ clu++;
num_clusters++;
} while (num_clusters < p_chain->size);
} else {
do {
- exfat_clear_bitmap(inode, clu);
-
- if (exfat_get_next_cluster(sb, &clu))
- goto dec_used_clus;
+ bool sync = false;
+ unsigned int n_clu = clu;
+ int err = exfat_get_next_cluster(sb, &n_clu);
+
+ if (err || n_clu == EXFAT_EOF_CLUSTER)
+ sync = true;
+ else
+ next_cmap_i =
+ BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(n_clu));
+
+ if (cur_cmap_i != next_cmap_i) {
+ sync = true;
+ cur_cmap_i = next_cmap_i;
+ }
+ exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode)));
+ clu = n_clu;
num_clusters++;
+
+ if (err)
+ goto dec_used_clus;
} while (clu != EXFAT_EOF_CLUSTER);
}