lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250407102345.50130-1-ailiop@suse.com>
Date: Mon,  7 Apr 2025 12:23:44 +0200
From: Anthony Iliopoulos <ailiop@...e.com>
To: Namjae Jeon <linkinjeon@...nel.org>,
	Sungjong Seo <sj1557.seo@...sung.com>,
	Yuezhang Mo <yuezhang.mo@...y.com>
Cc: linux-fsdevel@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: [PATCH] exfat: enable request merging for dir readahead

Directory listings that need to access the inode metadata (e.g. via
statx to obtain the file types) of large filesystems with lots of
metadata that aren't yet in dcache, will take a long time due to the
directory readahead submitting one io request at a time which although
targeting sequential disk sectors (up to EXFAT_MAX_RA_SIZE) are not
merged at the block layer.

Add plugging around sb_breadahead so that the requests can be batched
and submitted jointly to the block layer where they can be merged by the
io schedulers, instead of having each request individually submitted to
the hardware queues.

This significantly improves the throughput of directory listings as it
also minimizes the number of io completions and related handling from
the device driver side.

Signed-off-by: Anthony Iliopoulos <ailiop@...e.com>
---
 fs/exfat/dir.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c
index 3103b932b674..a46ab2690b4d 100644
--- a/fs/exfat/dir.c
+++ b/fs/exfat/dir.c
@@ -621,6 +621,7 @@ static int exfat_dir_readahead(struct super_block *sb, sector_t sec)
 {
 	struct exfat_sb_info *sbi = EXFAT_SB(sb);
 	struct buffer_head *bh;
+	struct blk_plug plug;
 	unsigned int max_ra_count = EXFAT_MAX_RA_SIZE >> sb->s_blocksize_bits;
 	unsigned int page_ra_count = PAGE_SIZE >> sb->s_blocksize_bits;
 	unsigned int adj_ra_count = max(sbi->sect_per_clus, page_ra_count);
@@ -644,8 +645,10 @@ static int exfat_dir_readahead(struct super_block *sb, sector_t sec)
 	if (!bh || !buffer_uptodate(bh)) {
 		unsigned int i;
 
+		blk_start_plug(&plug);
 		for (i = 0; i < ra_count; i++)
 			sb_breadahead(sb, (sector_t)(sec + i));
+		blk_finish_plug(&plug);
 	}
 	brelse(bh);
 	return 0;
-- 
2.49.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ