[PATCH 3/3] erofs-utils: use virtual file interface for the buffer manager

Gao Xiang hsiangkao at linux.alibaba.com
Thu Jul 17 02:24:41 AEST 2025


In order to prepare for the upcoming metadata compression.

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 include/erofs/cache.h    |  9 +++++----
 include/erofs/internal.h |  6 ------
 include/erofs/io.h       |  2 +-
 lib/cache.c              | 12 +++++++++---
 lib/io.c                 |  6 +++---
 mkfs/main.c              |  4 ++--
 6 files changed, 20 insertions(+), 19 deletions(-)

diff --git a/include/erofs/cache.h b/include/erofs/cache.h
index 0c665e8f..d5618c00 100644
--- a/include/erofs/cache.h
+++ b/include/erofs/cache.h
@@ -57,18 +57,18 @@ struct erofs_buffer_block {
 };
 
 struct erofs_bufmgr {
-	struct erofs_sb_info *sbi;
-
 	/* buckets for all buffer blocks to boost up allocation */
 	struct list_head watermeter[META + 1][2][EROFS_MAX_BLOCK_SIZE];
 	unsigned long bktmap[META + 1][2][EROFS_MAX_BLOCK_SIZE / BITS_PER_LONG];
 
 	struct erofs_buffer_block blkh;
-	erofs_blk_t tail_blkaddr, metablkcnt;
+	struct erofs_sb_info *sbi;
+	struct erofs_vfile *vf;
 
 	/* last mapped buffer block to accelerate erofs_mapbh() */
 	struct erofs_buffer_block *last_mapped_block;
 
+	erofs_blk_t tail_blkaddr, metablkcnt;
 	/* align data block addresses to multiples of `dsunit` */
 	unsigned int dsunit;
 };
@@ -122,7 +122,8 @@ static inline int erofs_bh_flush_generic_end(struct erofs_buffer_head *bh)
 }
 
 struct erofs_bufmgr *erofs_buffer_init(struct erofs_sb_info *sbi,
-				       erofs_blk_t startblk);
+				       erofs_blk_t startblk,
+				       struct erofs_vfile *vf);
 int erofs_bh_balloon(struct erofs_buffer_head *bh, erofs_off_t incr);
 
 struct erofs_buffer_head *erofs_balloc(struct erofs_bufmgr *bmgr,
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 65d40840..1431c16d 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -487,12 +487,6 @@ static inline int erofs_dev_write(struct erofs_sb_info *sbi, const void *buf,
 	return 0;
 }
 
-static inline int erofs_dev_fillzero(struct erofs_sb_info *sbi, u64 offset,
-				     size_t len, bool pad)
-{
-	return erofs_io_fallocate(&sbi->bdev, offset, len, pad);
-}
-
 static inline int erofs_dev_resize(struct erofs_sb_info *sbi,
 				   erofs_blk_t blocks)
 {
diff --git a/include/erofs/io.h b/include/erofs/io.h
index 101a5ba4..14d6e45f 100644
--- a/include/erofs/io.h
+++ b/include/erofs/io.h
@@ -59,7 +59,7 @@ ssize_t erofs_io_pwrite(struct erofs_vfile *vf, const void *buf, u64 pos, size_t
 ssize_t erofs_io_pwritev(struct erofs_vfile *vf, const struct iovec *iov,
 			 int iovcnt, u64 pos);
 int erofs_io_fsync(struct erofs_vfile *vf);
-ssize_t erofs_io_fallocate(struct erofs_vfile *vf, u64 offset, size_t len, bool pad);
+int erofs_io_fallocate(struct erofs_vfile *vf, u64 offset, size_t len, bool pad);
 int erofs_io_ftruncate(struct erofs_vfile *vf, u64 length);
 ssize_t erofs_io_pread(struct erofs_vfile *vf, void *buf, u64 offset, size_t len);
 ssize_t erofs_io_read(struct erofs_vfile *vf, void *buf, size_t len);
diff --git a/lib/cache.c b/lib/cache.c
index b3cf1c48..079465ed 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -29,7 +29,8 @@ const struct erofs_bhops erofs_skip_write_bhops = {
 };
 
 struct erofs_bufmgr *erofs_buffer_init(struct erofs_sb_info *sbi,
-				       erofs_blk_t startblk)
+				       erofs_blk_t startblk,
+				       struct erofs_vfile *vf)
 {
 	unsigned int blksiz = erofs_blksiz(sbi);
 	struct erofs_bufmgr *bmgr;
@@ -54,6 +55,7 @@ struct erofs_bufmgr *erofs_buffer_init(struct erofs_sb_info *sbi,
 	bmgr->last_mapped_block = &bmgr->blkh;
 	bmgr->metablkcnt = 0;
 	bmgr->dsunit = 0;
+	bmgr->vf = vf ?: &sbi->bdev;
 	return bmgr;
 }
 
@@ -482,9 +484,13 @@ int erofs_bflush(struct erofs_bufmgr *bmgr,
 			continue;
 
 		padding = blksiz - (p->buffers.off & (blksiz - 1));
-		if (padding != blksiz)
-			erofs_dev_fillzero(sbi, erofs_pos(sbi, blkaddr) - padding,
+		if (padding != blksiz) {
+			ret = erofs_io_fallocate(bmgr->vf,
+					   erofs_pos(sbi, blkaddr) - padding,
 					   padding, true);
+			if (ret < 0)
+				return ret;
+		}
 
 		if (p->type != DATA)
 			bmgr->metablkcnt += p->buffers.nblocks;
diff --git a/lib/io.c b/lib/io.c
index aa043cae..983d9bf9 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -147,8 +147,8 @@ int erofs_io_fsync(struct erofs_vfile *vf)
 	return 0;
 }
 
-ssize_t erofs_io_fallocate(struct erofs_vfile *vf, u64 offset,
-			   size_t len, bool zeroout)
+int erofs_io_fallocate(struct erofs_vfile *vf, u64 offset,
+		       size_t len, bool zeroout)
 {
 	static const char zero[EROFS_MAX_BLOCK_SIZE] = {0};
 	ssize_t ret;
@@ -167,7 +167,7 @@ ssize_t erofs_io_fallocate(struct erofs_vfile *vf, u64 offset,
 	while (len > EROFS_MAX_BLOCK_SIZE) {
 		ret = erofs_io_pwrite(vf, zero, offset, EROFS_MAX_BLOCK_SIZE);
 		if (ret < 0)
-			return ret;
+			return (int)ret;
 		len -= ret;
 		offset += ret;
 	}
diff --git a/mkfs/main.c b/mkfs/main.c
index fce26336..30804d10 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -1377,7 +1377,7 @@ int main(int argc, char **argv)
 	}
 
 	if (!incremental_mode) {
-		g_sbi.bmgr = erofs_buffer_init(&g_sbi, 0);
+		g_sbi.bmgr = erofs_buffer_init(&g_sbi, 0, NULL);
 		if (!g_sbi.bmgr) {
 			err = -ENOMEM;
 			goto exit;
@@ -1405,7 +1405,7 @@ int main(int argc, char **argv)
 			u.startblk = DIV_ROUND_UP(u.st.st_size, erofs_blksiz(&g_sbi));
 		else
 			u.startblk = g_sbi.primarydevice_blocks;
-		g_sbi.bmgr = erofs_buffer_init(&g_sbi, u.startblk);
+		g_sbi.bmgr = erofs_buffer_init(&g_sbi, u.startblk, NULL);
 		if (!g_sbi.bmgr) {
 			err = -ENOMEM;
 			goto exit;
-- 
2.43.5



More information about the Linux-erofs mailing list