Blame SOURCES/0049-exfat-write-multiple-sectors-at-once.patch

Kmods SIG 50e2b3
From 3db3c3fb840ed4a6c7666d1464959edd40fe54f1 Mon Sep 17 00:00:00 2001
Kmods SIG 50e2b3
From: Tetsuhiro Kohada <kohada.t2@gmail.com>
Kmods SIG 50e2b3
Date: Tue, 23 Jun 2020 15:22:19 +0900
Kmods SIG 50e2b3
Subject: [Backport 3db3c3fb840e] exfat: write multiple sectors at once
Kmods SIG 50e2b3
Kmods SIG 50e2b3
Write multiple sectors at once when updating dir-entries.
Kmods SIG 50e2b3
Add exfat_update_bhs() for that. It wait for write completion once
Kmods SIG 50e2b3
instead of sector by sector.
Kmods SIG 50e2b3
It's only effective if sync enabled.
Kmods SIG 50e2b3
Kmods SIG 50e2b3
Signed-off-by: Tetsuhiro Kohada <kohada.t2@gmail.com>
Kmods SIG 50e2b3
Signed-off-by: Namjae Jeon <namjae.jeon@samsung.com>
Kmods SIG 50e2b3
---
Kmods SIG 50e2b3
 src/dir.c      | 15 +++++++++------
Kmods SIG 50e2b3
 src/exfat_fs.h |  1 +
Kmods SIG 50e2b3
 src/misc.c     | 19 +++++++++++++++++++
Kmods SIG 50e2b3
 3 files changed, 29 insertions(+), 6 deletions(-)
Kmods SIG 50e2b3
Kmods SIG 50e2b3
diff --git a/src/dir.c b/src/dir.c
Kmods SIG 50e2b3
index 97296bc2b241cbe40b9a87e1f11ef8c203881680..542f1a5ab56fd60a2498f4437c85875cb07e9ef2 100644
Kmods SIG 50e2b3
--- a/src/dir.c
Kmods SIG 50e2b3
+++ b/src/dir.c
Kmods SIG 50e2b3
@@ -606,13 +606,16 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es)
Kmods SIG 50e2b3
 
Kmods SIG 50e2b3
 void exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync)
Kmods SIG 50e2b3
 {
Kmods SIG 50e2b3
-	int i;
Kmods SIG 50e2b3
+	int i, err = 0;
Kmods SIG 50e2b3
 
Kmods SIG 50e2b3
-	for (i = 0; i < es->num_bh; i++) {
Kmods SIG 50e2b3
-		if (es->modified)
Kmods SIG 50e2b3
-			exfat_update_bh(es->bh[i], sync);
Kmods SIG 50e2b3
-		brelse(es->bh[i]);
Kmods SIG 50e2b3
-	}
Kmods SIG 50e2b3
+	if (es->modified)
Kmods SIG 50e2b3
+		err = exfat_update_bhs(es->bh, es->num_bh, sync);
Kmods SIG 50e2b3
+
Kmods SIG 50e2b3
+	for (i = 0; i < es->num_bh; i++)
Kmods SIG 50e2b3
+		if (err)
Kmods SIG 50e2b3
+			bforget(es->bh[i]);
Kmods SIG 50e2b3
+		else
Kmods SIG 50e2b3
+			brelse(es->bh[i]);
Kmods SIG 50e2b3
 	kfree(es);
Kmods SIG 50e2b3
 }
Kmods SIG 50e2b3
 
Kmods SIG 50e2b3
diff --git a/src/exfat_fs.h b/src/exfat_fs.h
Kmods SIG 50e2b3
index 05553b2924ee313d9341bc8585f2290a10e8ff56..af0f526eece7bd05caa6a1b7fae28701776df5ed 100644
Kmods SIG 50e2b3
--- a/src/exfat_fs.h
Kmods SIG 50e2b3
+++ b/src/exfat_fs.h
Kmods SIG 50e2b3
@@ -513,6 +513,7 @@ void exfat_set_entry_time(struct exfat_sb_info *sbi, struct timespec64 *ts,
Kmods SIG 50e2b3
 u16 exfat_calc_chksum16(void *data, int len, u16 chksum, int type);
Kmods SIG 50e2b3
 u32 exfat_calc_chksum32(void *data, int len, u32 chksum, int type);
Kmods SIG 50e2b3
 void exfat_update_bh(struct buffer_head *bh, int sync);
Kmods SIG 50e2b3
+int exfat_update_bhs(struct buffer_head **bhs, int nr_bhs, int sync);
Kmods SIG 50e2b3
 void exfat_chain_set(struct exfat_chain *ec, unsigned int dir,
Kmods SIG 50e2b3
 		unsigned int size, unsigned char flags);
Kmods SIG 50e2b3
 void exfat_chain_dup(struct exfat_chain *dup, struct exfat_chain *ec);
Kmods SIG 50e2b3
diff --git a/src/misc.c b/src/misc.c
Kmods SIG 50e2b3
index 8a3dde59052bf04a4de6f65554df14ed6f185147..d34e6193258dd37117dba5fe27b5323b82dfedef 100644
Kmods SIG 50e2b3
--- a/src/misc.c
Kmods SIG 50e2b3
+++ b/src/misc.c
Kmods SIG 50e2b3
@@ -172,6 +172,25 @@ void exfat_update_bh(struct buffer_head *bh, int sync)
Kmods SIG 50e2b3
 		sync_dirty_buffer(bh);
Kmods SIG 50e2b3
 }
Kmods SIG 50e2b3
 
Kmods SIG 50e2b3
+int exfat_update_bhs(struct buffer_head **bhs, int nr_bhs, int sync)
Kmods SIG 50e2b3
+{
Kmods SIG 50e2b3
+	int i, err = 0;
Kmods SIG 50e2b3
+
Kmods SIG 50e2b3
+	for (i = 0; i < nr_bhs; i++) {
Kmods SIG 50e2b3
+		set_buffer_uptodate(bhs[i]);
Kmods SIG 50e2b3
+		mark_buffer_dirty(bhs[i]);
Kmods SIG 50e2b3
+		if (sync)
Kmods SIG 50e2b3
+			write_dirty_buffer(bhs[i], 0);
Kmods SIG 50e2b3
+	}
Kmods SIG 50e2b3
+
Kmods SIG 50e2b3
+	for (i = 0; i < nr_bhs && sync; i++) {
Kmods SIG 50e2b3
+		wait_on_buffer(bhs[i]);
Kmods SIG 50e2b3
+		if (!err && !buffer_uptodate(bhs[i]))
Kmods SIG 50e2b3
+			err = -EIO;
Kmods SIG 50e2b3
+	}
Kmods SIG 50e2b3
+	return err;
Kmods SIG 50e2b3
+}
Kmods SIG 50e2b3
+
Kmods SIG 50e2b3
 void exfat_chain_set(struct exfat_chain *ec, unsigned int dir,
Kmods SIG 50e2b3
 		unsigned int size, unsigned char flags)
Kmods SIG 50e2b3
 {
Kmods SIG 50e2b3
-- 
Kmods SIG 50e2b3
2.31.1
Kmods SIG 50e2b3