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 >