[PATCH] erofs-utils: lib: report leftovers for partially filled blocks

Gao Xiang hsiangkao at linux.alibaba.com
Fri Oct 18 17:24:17 AEDT 2024


3rd-party applications may need the exact zeroed sizes for each
partial filesystem block to fill remote data.

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 include/erofs/block_list.h |  2 +-
 lib/blobchunk.c            | 15 ++++++++++-----
 lib/block_list.c           | 10 +++++++---
 lib/inode.c                |  3 ++-
 4 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/include/erofs/block_list.h b/include/erofs/block_list.h
index 7db4d0c..8cc87d7 100644
--- a/include/erofs/block_list.h
+++ b/include/erofs/block_list.h
@@ -17,7 +17,7 @@ int erofs_blocklist_open(FILE *fp, bool srcmap);
 FILE *erofs_blocklist_close(void);
 
 void tarerofs_blocklist_write(erofs_blk_t blkaddr, erofs_blk_t nblocks,
-			      erofs_off_t srcoff);
+			      erofs_off_t srcoff, unsigned int zeroedlen);
 #ifdef WITH_ANDROID
 void erofs_droid_blocklist_write(struct erofs_inode *inode,
 				 erofs_blk_t blk_start, erofs_blk_t nblocks);
diff --git a/lib/blobchunk.c b/lib/blobchunk.c
index 9e85721..119dd82 100644
--- a/lib/blobchunk.c
+++ b/lib/blobchunk.c
@@ -133,12 +133,13 @@ static int erofs_blob_hashmap_cmp(const void *a, const void *b,
 int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
 				   erofs_off_t off)
 {
-	erofs_blk_t remaining_blks = BLK_ROUND_UP(inode->sbi, inode->i_size);
+	struct erofs_sb_info *sbi = inode->sbi;
+	erofs_blk_t remaining_blks = BLK_ROUND_UP(sbi, inode->i_size);
 	struct erofs_inode_chunk_index idx = {0};
 	erofs_blk_t extent_start = EROFS_NULL_ADDR;
 	erofs_blk_t extent_end, chunkblks;
 	erofs_off_t source_offset;
-	unsigned int dst, src, unit;
+	unsigned int dst, src, unit, zeroedlen;
 	bool first_extent = true;
 
 	if (inode->u.chunkformat & EROFS_CHUNK_FORMAT_INDEXES)
@@ -169,7 +170,7 @@ int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
 				remaining_blks -= extent_end - extent_start;
 				tarerofs_blocklist_write(extent_start,
 						extent_end - extent_start,
-						source_offset);
+						source_offset, 0);
 				erofs_droid_blocklist_write_extent(inode,
 					extent_start,
 					extent_end - extent_start,
@@ -190,9 +191,13 @@ int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
 	}
 	off = roundup(off, unit);
 	extent_end = min(extent_end, extent_start + remaining_blks);
-	if (extent_start != EROFS_NULL_ADDR)
+	if (extent_start != EROFS_NULL_ADDR) {
+		zeroedlen = inode->i_size & (erofs_blksiz(sbi) - 1);
+		if (zeroedlen)
+			zeroedlen = erofs_blksiz(sbi) - zeroedlen;
 		tarerofs_blocklist_write(extent_start, extent_end - extent_start,
-					 source_offset);
+					 source_offset, zeroedlen);
+	}
 	erofs_droid_blocklist_write_extent(inode, extent_start,
 			extent_start == EROFS_NULL_ADDR ?
 					0 : extent_end - extent_start,
diff --git a/lib/block_list.c b/lib/block_list.c
index 261e9ff..6bbe4ec 100644
--- a/lib/block_list.c
+++ b/lib/block_list.c
@@ -32,13 +32,17 @@ FILE *erofs_blocklist_close(void)
 
 /* XXX: really need to be cleaned up */
 void tarerofs_blocklist_write(erofs_blk_t blkaddr, erofs_blk_t nblocks,
-			      erofs_off_t srcoff)
+			      erofs_off_t srcoff, unsigned int zeroedlen)
 {
 	if (!block_list_fp || !nblocks || !srcmap_enabled)
 		return;
 
-	fprintf(block_list_fp, "%08x %8x %08" PRIx64 "\n",
-		blkaddr, nblocks, srcoff);
+	if (zeroedlen)
+		fprintf(block_list_fp, "%08x %8x %08" PRIx64 " %08u\n",
+			blkaddr, nblocks, srcoff, zeroedlen);
+	else
+		fprintf(block_list_fp, "%08x %8x %08" PRIx64 "\n",
+			blkaddr, nblocks, srcoff);
 }
 
 #ifdef WITH_ANDROID
diff --git a/lib/inode.c b/lib/inode.c
index 48f46b1..7abde7f 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1198,7 +1198,8 @@ static int erofs_inode_reserve_data_blocks(struct erofs_inode *inode)
 	erofs_bdrop(bh, false);
 
 	inode->datalayout = EROFS_INODE_FLAT_PLAIN;
-	tarerofs_blocklist_write(inode->u.i_blkaddr, nblocks, inode->i_ino[1]);
+	tarerofs_blocklist_write(inode->u.i_blkaddr, nblocks, inode->i_ino[1],
+				 alignedsz - inode->i_size);
 	return 0;
 }
 
-- 
2.43.5



More information about the Linux-erofs mailing list