Re: [PATCH] erofs-utils: mkfs: also handle last compacted 2B pack in z_erofs_drop_inline_pcluster

Zhiguo Niu <[email protected]>
Newsgroups org.ozlabs.lists.linux-erofs
Message-ID <CAHJ8P3LZk0jETzbetQzvbxx8XL-6nSVd6pUBK-SVOUK4gKPe_Q@mail.gmail.com>
version:
erofs-utils: 1.8.3
lz4:1.10.0
Android:17

cmd:
mkfs.erofs -z lz4hc,9 --compress-hints
./output/META/erofs_default_compress_hints.txt -d9 -b 4096
--mount-point product --fs-config-file
./output/META/product_filesystem_config.txt --file-contexts
./output/META/framework_file_contexts.bin -T 1230768000 -U
ad34a95d-293d-5e91-9234-c253209e9c71 -E dedupe,ztailpacking
./output/PRODUCT/tmp ./output/PRODUCT2/ 1>mkfs.log 2>&1
./fsck.erofs --extract -d9 output/PRODUCT/2sofiximage

error case:
mkfs 2 source files: libmsc.so.salsa, libmsc.so

erofs: failed to full decompress -3066 in[4096, 0] out[6121]
dump extent:
1192:  7765862.. 7770924 |    5062 :    9687040..   9691136 |    4096
1193:  7770924.. 7777021 |    6097 :    9691136..   9695232 |    4096
1194:  7777021.. 7784118 |    7097 :    9695232..   9699328 |    4096
1195:  7784118.. 7789918 |    5800 :    9699328..   9703424 |    4096
1196:  7789918.. 7797526 |    7608 :    9703424..   9707520 |    4096
1197:  7797526.. 7803647 |    6121 :    9707520..   9711616 |    4096
1198:  7803647.. 7806972 |    3325 :    9711616..   9715712 |    4096
mkfs debug log:
compacted_2b=1904  compacted_4b_initial=2 compacted_4b_end=0
write di_clusterof=2815 type=1 di_u.blkaddr=2371 d1=0 clusterofs=2815
//last pcluster
last 8 bytes in compacted pack:
6bfe0016 00000938
after drop inline operation:
0bfe0016 00000938

good case :
mkfs 1 source file:libmsc.so.salsa
dump extent:
1192:  7765862.. 7770924 |    5062 :    4886528..   4890624 |    4096
1193:  7770924.. 7777021 |    6097 :    4890624..   4894720 |    4096
1194:  7777021.. 7784118 |    7097 :    4894720..   4898816 |    4096
1195:  7784118.. 7789918 |    5800 :    4898816..   4902912 |    4096
1196:  7789918.. 7797526 |    7608 :    4902912..   4907008 |    4096
1197:  7797526.. 7805695 |    8169 :    4907008..   4911104 |    4096
1198:  7805695.. 7806972 |    1277 :    4911104..   4915200 |    4096
mkfs debug log:
compacted_2b=1904  compacted_4b_initial=0 compacted_4b_end=2
write di_clusterof=2815 type=1 di_u.blkaddr=1199 d1=0 clusterofs=2815
//last pcluster
last 8 bytes in compacted pack:
1aff2001 000004ae
after drop inline operation:
0aff2001 000004ae

Zhiguo Niu <[email protected]> 于2026年4月29日周三 16:00写道:
>
> With ztailpacking enabled, the current process assumes that a compacted_4b_end
> always exists in the compacted pack. However, in some specific files, the
> compacted pack may not have a compacted_4b_end. This leads to an incorrect
> modification of the last compacted_2B entry, resulting in incorrect modification
> of its clusterofs. In subsequent fsck operations, incorrect parameters will
> affect the decompression of the penultimate pcluster.
>
> This patch determines whether the last entry of the current compacted pack
> belongs to compacted 2B or 4B and then updates the correct bits accordingly.
>
> Fixes: a7c1f0575ef8 ("erofs-utils: lib: refine tailpcluster compression approach")
> Signed-off-by: Zhiguo Niu <[email protected]>
> ---
>  lib/compress.c | 38 +++++++++++++++++++++++++++-----------
>  1 file changed, 27 insertions(+), 11 deletions(-)
>
> diff --git a/lib/compress.c b/lib/compress.c
> index 62d2672..0eb464b 100644
> --- a/lib/compress.c
> +++ b/lib/compress.c
> @@ -1223,19 +1223,35 @@ void z_erofs_drop_inline_pcluster(struct erofs_inode *inode)
>
>                 di->di_advise = cpu_to_le16(type);
>         } else if (inode->datalayout == EROFS_INODE_COMPRESSED_COMPACT) {
> -               /* handle the last compacted 4B pack */
> +               /* handle the last compacted pack */
>                 unsigned int eofs, base, pos, v, lo;
>                 u8 *out;
> -
> -               eofs = inode->extent_isize -
> -                       (4 << (BLK_ROUND_UP(sbi, inode->i_size) & 1));
> -               base = round_down(eofs, 8);
> -               pos = 16 /* encodebits */ * ((eofs - base) / 4);
> -               out = inode->compressmeta + base;
> -               lo = erofs_blkoff(sbi, get_unaligned_le32(out + pos / 8));
> -               v = (type << sbi->blkszbits) | lo;
> -               out[pos / 8] = v & 0xff;
> -               out[pos / 8 + 1] = v >> 8;
> +               unsigned int compacted_4b_initial, compacted_2b, compacted_4b_end;
> +               unsigned int totalidx = BLK_ROUND_UP(sbi, inode->i_size);
> +               const erofs_off_t ebase = sizeof(struct z_erofs_map_header) +
> +                       round_up(erofs_iloc(inode) + inode->inode_isize +
> +                                       inode->xattr_isize, 8);
> +
> +               compacted_4b_initial = ((32 - ebase % 32) / 4) & 7;
> +               compacted_2b = 0;
> +               if ((le16_to_cpu(h->h_advise) & Z_EROFS_ADVISE_COMPACTED_2B) &&
> +                       compacted_4b_initial < totalidx)
> +                       compacted_2b = rounddown(totalidx - compacted_4b_initial, 16);
> +               compacted_4b_end = totalidx - compacted_4b_initial - compacted_2b;
> +               if (!compacted_2b || compacted_4b_end) {
> +                       eofs = inode->extent_isize - (4 << (totalidx & 1));
> +                       base = round_down(eofs, 8);
> +                       pos = 16 /* encodebits */ * ((eofs - base) / 4);
> +                       out = inode->compressmeta + base;
> +                       lo = erofs_blkoff(sbi, get_unaligned_le32(out + pos / 8));
> +                       v = (type << sbi->blkszbits) | lo;
> +                       out[pos / 8] = v & 0xff;
> +                       out[pos / 8 + 1] = v >> 8;
> +               } else {
> +                       eofs = inode->extent_isize - (4 + 1);
> +                       out = inode->compressmeta + eofs;
> +                       *out = (*out & 0x3f) | (type << 6);
> +               }
>         } else {
>                 DBG_BUGON(1);
>                 return;
> --
> 1.9.1
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.