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);
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;
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;
}
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
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();
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;