int erofs_iflush(struct erofs_inode *inode);
struct erofs_dentry *erofs_d_alloc(struct erofs_inode *parent,
const char *name);
+int erofs_allocate_inode_bh_data(struct erofs_inode *inode, erofs_blk_t nblocks);
bool erofs_dentry_is_wht(struct erofs_sb_info *sbi, struct erofs_dentry *d);
int erofs_rebuild_dump_tree(struct erofs_inode *dir, bool incremental);
int erofs_init_empty_dir(struct erofs_inode *dir);
u64 offset;
bool index_mode, headeronly_mode, rvsp_mode, aufs;
bool ddtaridx_mode;
+ bool try_no_reorder;
};
void erofs_iostream_close(struct erofs_iostream *ios);
return d;
}
-/* allocate main data for a inode */
-static int __allocate_inode_bh_data(struct erofs_inode *inode,
- unsigned long nblocks,
- int type)
+/* allocate main data for an inode */
+int erofs_allocate_inode_bh_data(struct erofs_inode *inode, erofs_blk_t nblocks)
{
struct erofs_bufmgr *bmgr = inode->sbi->bmgr;
struct erofs_buffer_head *bh;
- int ret;
+ int ret, type;
if (!nblocks) {
/* it has only tail-end data */
}
/* allocate main data buffer */
+ type = S_ISDIR(inode->i_mode) ? DIRA : DATA;
bh = erofs_balloc(bmgr, type, erofs_pos(inode->sbi, nblocks), 0, 0);
if (IS_ERR(bh))
return PTR_ERR(bh);
q = used = blkno = 0;
/* allocate dir main data */
- ret = __allocate_inode_bh_data(dir, erofs_blknr(sbi, dir->i_size), DIRA);
+ ret = erofs_allocate_inode_bh_data(dir, erofs_blknr(sbi, dir->i_size));
if (ret)
return ret;
inode->datalayout = EROFS_INODE_FLAT_INLINE;
- ret = __allocate_inode_bh_data(inode, nblocks, DATA);
+ ret = erofs_allocate_inode_bh_data(inode, nblocks);
if (ret)
return ret;
static int write_uncompressed_file_from_fd(struct erofs_inode *inode, int fd)
{
- int ret;
+ struct erofs_sb_info *sbi = inode->sbi;
erofs_blk_t nblocks, i;
unsigned int len;
- struct erofs_sb_info *sbi = inode->sbi;
+ int ret;
inode->datalayout = EROFS_INODE_FLAT_INLINE;
nblocks = inode->i_size >> sbi->blkszbits;
- ret = __allocate_inode_bh_data(inode, nblocks, DATA);
+ ret = erofs_allocate_inode_bh_data(inode, nblocks);
if (ret)
return ret;
erofs_strerror(-errno));
#endif
}
- ios->bufsize = 16384;
+ ios->bufsize = 32768;
}
do {
--inode->i_parent->i_nlink;
}
+static int tarerofs_write_uncompressed_file(struct erofs_inode *inode,
+ struct erofs_tarfile *tar)
+{
+ struct erofs_sb_info *sbi = inode->sbi;
+ erofs_blk_t nblocks;
+ erofs_off_t pos;
+ void *buf;
+ int ret;
+
+ inode->datalayout = EROFS_INODE_FLAT_PLAIN;
+ nblocks = DIV_ROUND_UP(inode->i_size, 1U << sbi->blkszbits);
+
+ ret = erofs_allocate_inode_bh_data(inode, nblocks);
+ if (ret)
+ return ret;
+
+ for (pos = 0; pos < inode->i_size; pos += ret) {
+ ret = erofs_iostream_read(&tar->ios, &buf, inode->i_size - pos);
+ if (ret < 0)
+ break;
+ if (erofs_dev_write(sbi, buf,
+ erofs_pos(sbi, inode->u.i_blkaddr) + pos,
+ ret)) {
+ ret = -EIO;
+ break;
+ }
+ }
+ inode->idata_size = 0;
+ inode->datasource = EROFS_INODE_DATA_SOURCE_NONE;
+ return 0;
+}
+
static int tarerofs_write_file_data(struct erofs_inode *inode,
struct erofs_tarfile *tar)
{
if (!ret && erofs_iostream_lskip(&tar->ios,
inode->i_size))
ret = -EIO;
+ } else if (tar->try_no_reorder &&
+ !cfg.c_compr_opts[0].alg &&
+ !cfg.c_inline_data) {
+ ret = tarerofs_write_uncompressed_file(inode, tar);
} else {
ret = tarerofs_write_file_data(inode, tar);
}
would overflow compact inodes. This is the default. Overrides
.BR --ignore-mtime .
.TP
-.BI "\-\-tar, \-\-tar="MODE
+.BI "\-\-sort=" MODE
+Inode data sorting order for tarballs as input.
+
+\fIMODE\fR may be one of \fBnone\fR or \fBpath\fR.
+
+\fBnone\fR: No particular data order is specified for the target image to
+avoid unnecessary overhead; Currently, it takes effect if `-E^inline_data` is
+specified and no compression is applied.
+
+\fBpath\fR: Data order strictly follows the tree generation order. (default)
+.TP
+.BI "\-\-tar, \-\-tar=" MODE
Treat \fISOURCE\fR as a tarball or tarball-like "headerball" rather than as a
directory.
{"root-xattr-isize", required_argument, NULL, 524},
{"mkfs-time", no_argument, NULL, 525},
{"all-time", no_argument, NULL, 526},
+ {"sort", required_argument, NULL, 527},
{0, 0, 0, 0},
};
" --offset=# skip # bytes at the beginning of IMAGE.\n"
" --root-xattr-isize=# ensure the inline xattr size of the root directory is # bytes at least\n"
" --aufs replace aufs special files with overlayfs metadata\n"
+ " --sort=<path,none> data sorting order for tarballs as input (default: path)\n"
" --tar=X generate a full or index-only image from a tarball(-ish) source\n"
" (X = f|i|headerball; f=full mode, i=index mode,\n"
" headerball=file data is omited in the source stream)\n"
case 526:
cfg.c_timeinherit = TIMESTAMP_FIXED;
break;
+ case 527:
+ if (!strcmp(optarg, "none"))
+ erofstar.try_no_reorder = true;
+ break;
case 'V':
version();
exit(0);