[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