.. Instead of reporting IO errors which implies a corrupted image.

Fixes: 6894ca9623e7 ("erofs-utils: mkfs: Support tar source without data")
Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com>
---
 include/erofs/blobchunk.h |  1 +
 lib/blobchunk.c           | 41 +++++++++++++++++++++++++++++++++++++++
 lib/tar.c                 |  6 ++++--
 mkfs/main.c               | 18 +++++++++--------
 4 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/include/erofs/blobchunk.h b/include/erofs/blobchunk.h
index 89c8048..a674640 100644
--- a/include/erofs/blobchunk.h
+++ b/include/erofs/blobchunk.h
@@ -19,6 +19,7 @@ struct erofs_blobchunk *erofs_get_unhashed_chunk(unsigned int 
device_id,
 int erofs_blob_write_chunk_indexes(struct erofs_inode *inode, erofs_off_t off);
 int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd,
                                  erofs_off_t startoff);
+int erofs_write_zero_inode(struct erofs_inode *inode);
 int tarerofs_write_chunkes(struct erofs_inode *inode, erofs_off_t data_offset);
 int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi);
 void erofs_blob_exit(void);
diff --git a/lib/blobchunk.c b/lib/blobchunk.c
index 6d2501e..ee12194 100644
--- a/lib/blobchunk.c
+++ b/lib/blobchunk.c
@@ -338,6 +338,47 @@ err:
        return ret;
 }
 
+int erofs_write_zero_inode(struct erofs_inode *inode)
+{
+       struct erofs_sb_info *sbi = inode->sbi;
+       unsigned int chunkbits = ilog2(inode->i_size - 1) + 1;
+       unsigned int count;
+       erofs_off_t chunksize, len, pos;
+       struct erofs_inode_chunk_index *idx;
+
+       if (chunkbits < sbi->blkszbits)
+               chunkbits = sbi->blkszbits;
+       if (chunkbits - sbi->blkszbits > EROFS_CHUNK_FORMAT_BLKBITS_MASK)
+               chunkbits = EROFS_CHUNK_FORMAT_BLKBITS_MASK + sbi->blkszbits;
+
+       inode->u.chunkformat |= chunkbits - sbi->blkszbits;
+
+       chunksize = 1ULL << chunkbits;
+       count = DIV_ROUND_UP(inode->i_size, chunksize);
+
+       inode->extent_isize = count * EROFS_BLOCK_MAP_ENTRY_SIZE;
+       idx = calloc(count, max(sizeof(*idx), sizeof(void *)));
+       if (!idx)
+               return -ENOMEM;
+       inode->chunkindexes = idx;
+
+       for (pos = 0; pos < inode->i_size; pos += len) {
+               struct erofs_blobchunk *chunk;
+
+               len = min_t(erofs_off_t, inode->i_size - pos, chunksize);
+               chunk = erofs_get_unhashed_chunk(0, EROFS_NULL_ADDR, -1);
+               if (IS_ERR(chunk)) {
+                       free(inode->chunkindexes);
+                       inode->chunkindexes = NULL;
+                       return PTR_ERR(chunk);
+               }
+
+               *(void **)idx++ = chunk;
+       }
+       inode->datalayout = EROFS_INODE_CHUNK_BASED;
+       return 0;
+}
+
 int tarerofs_write_chunkes(struct erofs_inode *inode, erofs_off_t data_offset)
 {
        struct erofs_sb_info *sbi = inode->sbi;
diff --git a/lib/tar.c b/lib/tar.c
index fe7fdd3..7c271f6 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -645,7 +645,7 @@ static int tarerofs_write_file_index(struct erofs_inode 
*inode,
        ret = tarerofs_write_chunkes(inode, data_offset);
        if (ret)
                return ret;
-       if (!tar->headeronly_mode && erofs_iostream_lskip(&tar->ios, 
inode->i_size))
+       if (erofs_iostream_lskip(&tar->ios, inode->i_size))
                return -EIO;
        return 0;
 }
@@ -1002,7 +1002,9 @@ new_inode:
                        inode->i_link = malloc(inode->i_size + 1);
                        memcpy(inode->i_link, eh.link, inode->i_size + 1);
                } else if (inode->i_size) {
-                       if (tar->index_mode)
+                       if (tar->headeronly_mode)
+                               ret = erofs_write_zero_inode(inode);
+                       else if (tar->index_mode)
                                ret = tarerofs_write_file_index(inode, tar,
                                                                data_offset);
                        else
diff --git a/mkfs/main.c b/mkfs/main.c
index e9f0522..2fb4a57 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -1260,12 +1260,14 @@ int main(int argc, char **argv)
                        return 1;
        }
 
-       if ((erofstar.index_mode && !erofstar.mapfile) || cfg.c_blobdev_path)
+       if (((erofstar.index_mode && !erofstar.headeronly_mode) &&
+           !erofstar.mapfile) || cfg.c_blobdev_path) {
                err = erofs_mkfs_init_devices(&sbi, 1);
-       if (err) {
-               erofs_err("failed to generate device table: %s",
-                         erofs_strerror(err));
-               goto exit;
+               if (err) {
+                       erofs_err("failed to generate device table: %s",
+                                 erofs_strerror(err));
+                       goto exit;
+               }
        }
 
        erofs_inode_manager_init();
@@ -1318,10 +1320,10 @@ int main(int argc, char **argv)
        root_nid = erofs_lookupnid(root_inode);
        erofs_iput(root_inode);
 
+       if (erofstar.index_mode && sbi.extra_devices && !erofstar.mapfile)
+               sbi.devs[0].blocks = BLK_ROUND_UP(&sbi, erofstar.offset);
+
        if (erofstar.index_mode || cfg.c_chunkbits || sbi.extra_devices) {
-               if (erofstar.index_mode && !erofstar.mapfile)
-                       sbi.devs[0].blocks =
-                               BLK_ROUND_UP(&sbi, erofstar.offset);
                err = erofs_mkfs_dump_blobs(&sbi);
                if (err)
                        goto exit;
-- 
2.39.3

Reply via email to