erofs-utils: lib: report leftovers for partially filled blocks
authorGao Xiang <hsiangkao@linux.alibaba.com>
Fri, 18 Oct 2024 06:24:17 +0000 (14:24 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Mon, 21 Oct 2024 09:41:41 +0000 (17:41 +0800)
3rd-party applications may need the exact zeroed size for each
partial filesystem block to populate remote data.

Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Link: https://lore.kernel.org/r/20241018062417.2297930-1-hsiangkao@linux.alibaba.com
include/erofs/block_list.h
lib/blobchunk.c
lib/block_list.c
lib/inode.c

index 7db4d0c135f5eaaf9a4b5f71896b9c6e82d8416f..8cc87d7b553c208729da9106967b8b5f8bdaeef5 100644 (file)
@@ -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);
index 9e857210fb9741c8531402db2fb7aaadfabbf503..119dd82934043734c0dfc9e31eb8da93ec4b5c2f 100644 (file)
@@ -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,
index 261e9ff5f3c3ee1f08853ae12834068e04328ed9..6bbe4ec816e786bb97521b758561d37079556665 100644 (file)
@@ -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
index 48f46b17a0037f21389e97905b7930c477f9aa99..7abde7f4a3b5482afa9bdf7de7cde8a65629ad65 100644 (file)
@@ -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;
 }