.. 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