[PATCH 2/3] erofs-utils: mkfs: limit the default asynchronous queue size

Gao Xiang hsiangkao at linux.alibaba.com
Sat Jun 14 12:32:58 AEST 2025


Limit the default asynchronous queue size based on the maximum file
descriptor limit.

Otherwise, exceeding the FD limit will result in EMFILE errors.

Note that EROFS reuses the file page cache instead of duplicating all
file contents into process memory, though this is constrained by the
maximum FD limit.

Fixes: 9bd592bfed10 ("erofs-utils: mkfs: increase the maximum size of the asynchronous queue")
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 configure.ac |  2 ++
 lib/inode.c  | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/configure.ac b/configure.ac
index a73a9ba..5c2737c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -211,6 +211,7 @@ AC_CHECK_HEADERS(m4_flatten([
 	sys/ioctl.h
 	sys/mman.h
 	sys/random.h
+	sys/resource.h
 	sys/sendfile.h
 	sys/stat.h
 	sys/statfs.h
@@ -265,6 +266,7 @@ AC_CHECK_FUNCS(m4_flatten([
 	backtrace
 	copy_file_range
 	fallocate
+	getrlimit
 	gettimeofday
 	lgetxattr
 	llistxattr
diff --git a/lib/inode.c b/lib/inode.c
index 7bd1047..39ffebc 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1888,6 +1888,28 @@ static int __erofs_mkfs_build_tree(struct erofs_mkfs_buildtree_ctx *ctx)
 }
 
 #ifdef EROFS_MT_ENABLED
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+
+static int erofs_get_fdlimit(void)
+{
+#if defined(HAVE_SYS_RESOURCE_H) && defined(HAVE_GETRLIMIT)
+	struct rlimit rlim;
+	int err;
+
+	err = getrlimit(RLIMIT_NOFILE, &rlim);
+	if (err < 0)
+		return _POSIX_OPEN_MAX;
+	if (rlim.rlim_cur == RLIM_INFINITY)
+		return 0;
+	return rlim.rlim_cur;
+#else
+	return _POSIX_OPEN_MAX;
+#endif
+}
+
 static int erofs_mkfs_build_tree(struct erofs_mkfs_buildtree_ctx *ctx)
 {
 	struct erofs_mkfs_dfops *q;
@@ -1898,7 +1920,14 @@ static int erofs_mkfs_build_tree(struct erofs_mkfs_buildtree_ctx *ctx)
 	if (!q)
 		return -ENOMEM;
 
-	q->entries = cfg.c_mt_async_queue_limit ?: 32768;
+	if (cfg.c_mt_async_queue_limit) {
+		q->entries = cfg.c_mt_async_queue_limit;
+	} else {
+		err = roundup_pow_of_two(erofs_get_fdlimit()) >> 1;
+		q->entries = err && err < 32768 ? err : 32768;
+	}
+	erofs_dbg("Set the asynchronous queue size to %u", q->entries);
+
 	q->queue = malloc(q->entries * sizeof(*q->queue));
 	if (!q->queue) {
 		free(q);
-- 
2.43.5



More information about the Linux-erofs mailing list