[PATCH] erofs-utils: mkfs: avoid hanging if fragment is on and tmpdir is full

Gao Xiang hsiangkao at linux.alibaba.com
Wed Feb 4 17:29:48 AEDT 2026


The main thread should respond to errors from the child process
instead of waiting indefinitely.

Reported-by: Daniel Colascione <dancol at dancol.org>
Closes: https://github.com/erofs/erofs-utils/issues/34
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 lib/compress.c | 14 +++++++++++---
 lib/inode.c    |  1 +
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/lib/compress.c b/lib/compress.c
index 58d1f4d..222e380 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -1338,8 +1338,11 @@ int erofs_commit_compressed_file(struct z_erofs_compress_ictx *ictx,
 
 	if (inode->fragment_size) {
 		ret = erofs_fragment_commit(inode, ictx->tofh);
-		if (ret)
+		if (ret) {
+			erofs_err("failed to commit fragment for %s: %s",
+				  inode->i_srcpath, erofs_strerror(ret));
 			goto err_free_idata;
+		}
 		inode->z_advise |= Z_EROFS_ADVISE_FRAGMENT_PCLUSTER;
 		erofs_sb_set_fragments(sbi);
 	}
@@ -1822,8 +1825,13 @@ void *erofs_prepare_compressed_file(struct erofs_importer *im,
 	if (!z_erofs_mt_enabled || all_fragments) {
 #ifdef EROFS_MT_ENABLED
 		pthread_mutex_lock(&g_ictx.mutex);
-		if (g_ictx.seg_num)
+		while (g_ictx.seg_num) {
+			if (g_ictx.seg_num == INT_MAX) {
+				pthread_mutex_unlock(&g_ictx.mutex);
+				return ERR_PTR(-ECHILD);
+			}
 			pthread_cond_wait(&g_ictx.cond, &g_ictx.mutex);
+		}
 		g_ictx.seg_num = 1;
 		pthread_mutex_unlock(&g_ictx.mutex);
 #endif
@@ -1974,7 +1982,7 @@ err_free_idata:
 out:
 #ifdef EROFS_MT_ENABLED
 	pthread_mutex_lock(&ictx->mutex);
-	ictx->seg_num = 0;
+	ictx->seg_num = ret < 0 ? INT_MAX : 0;
 	pthread_cond_signal(&ictx->cond);
 	pthread_mutex_unlock(&ictx->mutex);
 #endif
diff --git a/lib/inode.c b/lib/inode.c
index 7d20fbd..79e5d3b 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -786,6 +786,7 @@ int erofs_iflush(struct erofs_inode *inode)
 	bool nlink_1 = true;
 	int ret, fmt;
 
+	DBG_BUGON(inode->nid == EROFS_NID_UNALLOCATED);
 	DBG_BUGON(bh && erofs_btell(bh, false) != off);
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
 	    S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
-- 
2.43.0



More information about the Linux-erofs mailing list