Blob Blame History Raw
From 23befe490ba885bdf757d40b2489134315fef690 Mon Sep 17 00:00:00 2001
From: Hyeongseok Kim <hyeongseok@gmail.com>
Date: Mon, 15 Mar 2021 13:12:55 +0900
Subject: [Backport 23befe490ba8] exfat: improve write performance when dirsync
 enabled

Degradation of write speed caused by frequent disk access for cluster
bitmap update on every cluster allocation could be improved by
selective syncing bitmap buffer. Change to flush bitmap buffer only
for the directory related operations.

Signed-off-by: Hyeongseok Kim <hyeongseok@gmail.com>
Acked-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
---
 src/balloc.c   | 4 ++--
 src/dir.c      | 2 +-
 src/exfat_fs.h | 4 ++--
 src/fatent.c   | 4 ++--
 src/inode.c    | 3 ++-
 src/namei.c    | 2 +-
 6 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/src/balloc.c b/src/balloc.c
index 78bc87d5a11bf9688dbef42ad9c3b4f0c232c0f1..cc5cffc4a76910cb2ed3c36f1fcadd4ccb9b1679 100644
--- a/src/balloc.c
+++ b/src/balloc.c
@@ -141,7 +141,7 @@ void exfat_free_bitmap(struct exfat_sb_info *sbi)
 	kfree(sbi->vol_amap);
 }
 
-int exfat_set_bitmap(struct inode *inode, unsigned int clu)
+int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync)
 {
 	int i, b;
 	unsigned int ent_idx;
@@ -154,7 +154,7 @@ int exfat_set_bitmap(struct inode *inode, unsigned int clu)
 	b = BITMAP_OFFSET_BIT_IN_SECTOR(sb, ent_idx);
 
 	set_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);
 	return 0;
 }
 
diff --git a/src/dir.c b/src/dir.c
index e1d5536de948b3dcd4667cf3074b51462ddb0697..7efb1c6d480846937da5436277b6220dd26f2f7c 100644
--- a/src/dir.c
+++ b/src/dir.c
@@ -320,7 +320,7 @@ int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu)
 
 	exfat_chain_set(clu, EXFAT_EOF_CLUSTER, 0, ALLOC_NO_FAT_CHAIN);
 
-	ret = exfat_alloc_cluster(inode, 1, clu);
+	ret = exfat_alloc_cluster(inode, 1, clu, IS_DIRSYNC(inode));
 	if (ret)
 		return ret;
 
diff --git a/src/exfat_fs.h b/src/exfat_fs.h
index 169d0b602f5e7c06c8889b38d83abcfad2e8382c..e77fe2f45cf28fe8533276426a73c657446863f6 100644
--- a/src/exfat_fs.h
+++ b/src/exfat_fs.h
@@ -389,7 +389,7 @@ int exfat_clear_volume_dirty(struct super_block *sb);
 #define exfat_get_next_cluster(sb, pclu) exfat_ent_get(sb, *(pclu), pclu)
 
 int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
-		struct exfat_chain *p_chain);
+		struct exfat_chain *p_chain, bool sync_bmap);
 int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain);
 int exfat_ent_get(struct super_block *sb, unsigned int loc,
 		unsigned int *content);
@@ -408,7 +408,7 @@ int exfat_count_num_clusters(struct super_block *sb,
 /* balloc.c */
 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);
+int exfat_set_bitmap(struct inode *inode, unsigned int clu, bool sync);
 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);
diff --git a/src/fatent.c b/src/fatent.c
index fd6c7fd127620fc405cff2b5ae2d6fae5be25422..e949e563443c937bc80b13b6cd502a0e0a32c68d 100644
--- a/src/fatent.c
+++ b/src/fatent.c
@@ -320,7 +320,7 @@ int exfat_zeroed_cluster(struct inode *dir, unsigned int clu)
 }
 
 int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
-		struct exfat_chain *p_chain)
+		struct exfat_chain *p_chain, bool sync_bmap)
 {
 	int ret = -ENOSPC;
 	unsigned int num_clusters = 0, total_cnt;
@@ -388,7 +388,7 @@ int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
 		}
 
 		/* update allocation bitmap */
-		if (exfat_set_bitmap(inode, new_clu)) {
+		if (exfat_set_bitmap(inode, new_clu, sync_bmap)) {
 			ret = -EIO;
 			goto free_cluster;
 		}
diff --git a/src/inode.c b/src/inode.c
index 730373e0965aff2a8c366b34482c61afeec9cd56..1803ef3220fdbd6ca51470b736ca3ab596588fc3 100644
--- a/src/inode.c
+++ b/src/inode.c
@@ -179,7 +179,8 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset,
 			return -EIO;
 		}
 
-		ret = exfat_alloc_cluster(inode, num_to_be_allocated, &new_clu);
+		ret = exfat_alloc_cluster(inode, num_to_be_allocated, &new_clu,
+				inode_needs_sync(inode));
 		if (ret)
 			return ret;
 
diff --git a/src/namei.c b/src/namei.c
index d9e8ec689c55ca3e8511177de0c01dfe1d3c090a..1f7b3dc66fcd6fd5507f9d52d73d01cb69433afd 100644
--- a/src/namei.c
+++ b/src/namei.c
@@ -340,7 +340,7 @@ static int exfat_find_empty_entry(struct inode *inode,
 		exfat_chain_set(&clu, last_clu + 1, 0, p_dir->flags);
 
 		/* allocate a cluster */
-		ret = exfat_alloc_cluster(inode, 1, &clu);
+		ret = exfat_alloc_cluster(inode, 1, &clu, IS_DIRSYNC(inode));
 		if (ret)
 			return ret;
 
-- 
2.31.1