aboutsummaryrefslogtreecommitdiff
path: root/lib/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/inode.c')
-rw-r--r--lib/inode.c68
1 files changed, 49 insertions, 19 deletions
diff --git a/lib/inode.c b/lib/inode.c
index 77ea8bf..f192510 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0
/*
* Copyright (C) 2018-2019 HUAWEI, Inc.
* http://www.huawei.com/
@@ -96,6 +96,8 @@ unsigned int erofs_iput(struct erofs_inode *inode)
list_for_each_entry_safe(d, t, &inode->i_subdirs, d_child)
free(d);
+ if (inode->eof_tailraw)
+ free(inode->eof_tailraw);
list_del(&inode->i_hash);
free(inode);
return 0;
@@ -593,28 +595,31 @@ static int erofs_prepare_inode_buffer(struct erofs_inode *inode)
inodesize = Z_EROFS_VLE_EXTENT_ALIGN(inodesize) +
inode->extent_isize;
- if (is_inode_layout_compression(inode))
- goto noinline;
+ /* TODO: tailpacking inline of chunk-based format isn't finalized */
if (inode->datalayout == EROFS_INODE_CHUNK_BASED)
goto noinline;
- if (cfg.c_noinline_data && S_ISREG(inode->i_mode)) {
- inode->datalayout = EROFS_INODE_FLAT_PLAIN;
- goto noinline;
+ if (!is_inode_layout_compression(inode)) {
+ if (cfg.c_noinline_data && S_ISREG(inode->i_mode)) {
+ inode->datalayout = EROFS_INODE_FLAT_PLAIN;
+ goto noinline;
+ }
+ /*
+ * If the file sizes of uncompressed files are block-aligned,
+ * should use the EROFS_INODE_FLAT_PLAIN data layout.
+ */
+ if (!inode->idata_size)
+ inode->datalayout = EROFS_INODE_FLAT_PLAIN;
}
- /*
- * if the file size is block-aligned for uncompressed files,
- * should use EROFS_INODE_FLAT_PLAIN data mapping mode.
- */
- if (!inode->idata_size)
- inode->datalayout = EROFS_INODE_FLAT_PLAIN;
-
bh = erofs_balloc(INODE, inodesize, 0, inode->idata_size);
if (bh == ERR_PTR(-ENOSPC)) {
int ret;
- inode->datalayout = EROFS_INODE_FLAT_PLAIN;
+ if (is_inode_layout_compression(inode))
+ z_erofs_drop_inline_pcluster(inode);
+ else
+ inode->datalayout = EROFS_INODE_FLAT_PLAIN;
noinline:
/* expend an extra block for tail-end data */
ret = erofs_prepare_tail_block(inode);
@@ -627,7 +632,17 @@ noinline:
} else if (IS_ERR(bh)) {
return PTR_ERR(bh);
} else if (inode->idata_size) {
- inode->datalayout = EROFS_INODE_FLAT_INLINE;
+ if (is_inode_layout_compression(inode)) {
+ DBG_BUGON(!cfg.c_ztailpacking);
+ erofs_dbg("Inline %scompressed data (%u bytes) to %s",
+ inode->compressed_idata ? "" : "un",
+ inode->idata_size, inode->i_srcpath);
+ erofs_sb_set_ztailpacking();
+ } else {
+ inode->datalayout = EROFS_INODE_FLAT_INLINE;
+ erofs_dbg("Inline tail-end data (%u bytes) to %s",
+ inode->idata_size, inode->i_srcpath);
+ }
/* allocate inline buffer */
ibh = erofs_battach(bh, META, inode->idata_size);
@@ -685,15 +700,26 @@ static int erofs_write_tail_end(struct erofs_inode *inode)
erofs_droid_blocklist_write_tail_end(inode, NULL_ADDR);
} else {
int ret;
- erofs_off_t pos;
+ erofs_off_t pos, zero_pos;
erofs_mapbh(bh->block);
pos = erofs_btell(bh, true) - EROFS_BLKSIZ;
+
+ /* 0'ed data should be padded at head for 0padding conversion */
+ if (erofs_sb_has_lz4_0padding() && inode->compressed_idata) {
+ zero_pos = pos;
+ pos += EROFS_BLKSIZ - inode->idata_size;
+ } else {
+ /* pad 0'ed data for the other cases */
+ zero_pos = pos + inode->idata_size;
+ }
ret = dev_write(inode->idata, pos, inode->idata_size);
if (ret)
return ret;
+
+ DBG_BUGON(inode->idata_size > EROFS_BLKSIZ);
if (inode->idata_size < EROFS_BLKSIZ) {
- ret = dev_fillzero(pos + inode->idata_size,
+ ret = dev_fillzero(zero_pos,
EROFS_BLKSIZ - inode->idata_size,
false);
if (ret)
@@ -1057,7 +1083,7 @@ static struct erofs_inode *erofs_mkfs_build_tree(struct erofs_inode *dir)
erofs_fixup_meta_blkaddr(dir);
list_for_each_entry(d, &dir->i_subdirs, d_child) {
- char buf[PATH_MAX];
+ char buf[PATH_MAX], *trimmed;
unsigned char ftype;
if (is_dot_dotdot(d->name)) {
@@ -1072,6 +1098,10 @@ static struct erofs_inode *erofs_mkfs_build_tree(struct erofs_inode *dir)
goto fail;
}
+ trimmed = erofs_trim_for_progressinfo(erofs_fspath(buf),
+ sizeof("Processing ...") - 1);
+ erofs_update_progressinfo("Processing %s ...", trimmed);
+ free(trimmed);
d->inode = erofs_mkfs_build_tree_from_path(dir, buf);
if (IS_ERR(d->inode)) {
ret = PTR_ERR(d->inode);
@@ -1086,7 +1116,7 @@ fail:
d->type = ftype;
erofs_d_invalidate(d);
- erofs_info("add file %s/%s (nid %llu, type %d)",
+ erofs_info("add file %s/%s (nid %llu, type %u)",
dir->i_srcpath, d->name, (unsigned long long)d->nid,
d->type);
}