[PATCH] erofs-utils: mkfs: forget all dirty buffers on failure

Gao Xiang hsiangkao at linux.alibaba.com
Tue Dec 23 21:12:21 AEDT 2025


When mkfs fails (e.g., due to network or I/O errors), dirty buffers may
still be queued for write:
```
<E> erofs: s3erofs_request_perform() Line[605] curl_easy_perform() failed: SSL peer certificate or SSH remote key was not OK
<E> erofs: s3erofs_build_trees() Line[1076] failed to get next object: [Error 5] Input/output error
<E> erofs: main() Line[2029]    Could not format the device : [Error 5] Input/output error

mkfs.erofs: cache.c:536: void erofs_buffer_exit(struct erofs_bufmgr *): Assertion `!(!list_empty(&bmgr->blkh.list))' failed.
```

Fixes: a482ef7d1fdf ("erofs-utils: mkfs: fix memleak in error exit path")
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 lib/cache.c | 17 +++++++++++++----
 mkfs/main.c |  2 +-
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/lib/cache.c b/lib/cache.c
index 24449f221317..a87575ad74d1 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -448,8 +448,8 @@ static void erofs_bfree(struct erofs_buffer_block *bb)
 	free(bb);
 }
 
-int erofs_bflush(struct erofs_bufmgr *bmgr,
-		 struct erofs_buffer_block *bb)
+static int __erofs_bflush(struct erofs_bufmgr *bmgr,
+			  struct erofs_buffer_block *bb, bool forget)
 {
 	struct erofs_sb_info *sbi = bmgr->sbi;
 	const unsigned int blksiz = erofs_blksiz(sbi);
@@ -470,8 +470,11 @@ int erofs_bflush(struct erofs_bufmgr *bmgr,
 
 		list_for_each_entry_safe(bh, nbh, &p->buffers.list, list) {
 			if (bh->op == &erofs_skip_write_bhops) {
-				skip = true;
-				continue;
+				if (!forget) {
+					skip = true;
+					continue;
+				}
+				bh->op = &erofs_drop_directly_bhops;
 			}
 
 			/* flush and remove bh */
@@ -501,6 +504,11 @@ int erofs_bflush(struct erofs_bufmgr *bmgr,
 	return 0;
 }
 
+int erofs_bflush(struct erofs_bufmgr *bmgr, struct erofs_buffer_block *bb)
+{
+	return __erofs_bflush(bmgr, bb, false);
+}
+
 void erofs_bdrop(struct erofs_buffer_head *bh, bool tryrevoke)
 {
 	struct erofs_buffer_block *const bb = bh->block;
@@ -533,6 +541,7 @@ erofs_blk_t erofs_total_metablocks(struct erofs_bufmgr *bmgr)
 
 void erofs_buffer_exit(struct erofs_bufmgr *bmgr)
 {
+	DBG_BUGON(__erofs_bflush(bmgr, NULL, true));
 	DBG_BUGON(!list_empty(&bmgr->blkh.list));
 	free(bmgr);
 }
diff --git a/mkfs/main.c b/mkfs/main.c
index 22201d35dedf..aaa0300bca1b 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -1997,7 +1997,6 @@ exit:
 	blklst = erofs_blocklist_close();
 	if (blklst)
 		fclose(blklst);
-	erofs_dev_close(&g_sbi);
 	erofs_cleanup_compress_hints();
 	erofs_cleanup_exclude_rules();
 	if (cfg.c_chunkbits || source_mode == EROFS_MKFS_SOURCE_REBUILD)
@@ -2033,6 +2032,7 @@ exit:
 		erofs_mkfs_showsummaries();
 	}
 	erofs_put_super(&g_sbi);
+	erofs_dev_close(&g_sbi);
 	liberofs_global_exit();
 	return err;
 }
-- 
2.43.5



More information about the Linux-erofs mailing list