3rd-party applications may need the exact zeroed sizes for each partial filesystem block to fill remote data.
Signed-off-by: Gao Xiang <hsiang...@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