mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 20:54:10 +08:00
erofs: fix up compacted indexes for block size < 4096
Previously, the block size always equaled to PAGE_SIZE, therefore `lclusterbits` couldn't be less than 12. Since sub-page compressed blocks are now considered, `lobits` for a lcluster in each pack cannot always be `lclusterbits` as before. Otherwise, there is no enough room for the special value `Z_EROFS_LI_D0_CBLKCNT`. To support smaller block sizes, `lobits` for each compacted lcluster is now calculated as: lobits = max(lclusterbits, ilog2(Z_EROFS_LI_D0_CBLKCNT) + 1) Reviewed-by: Yue Hu <huyue2@coolpad.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20231206091057.87027-4-hsiangkao@linux.alibaba.com
This commit is contained in:
parent
54ed3fdd66
commit
8d2517aaee
@ -82,29 +82,26 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m,
|
||||
}
|
||||
|
||||
static unsigned int decode_compactedbits(unsigned int lobits,
|
||||
unsigned int lomask,
|
||||
u8 *in, unsigned int pos, u8 *type)
|
||||
{
|
||||
const unsigned int v = get_unaligned_le32(in + pos / 8) >> (pos & 7);
|
||||
const unsigned int lo = v & lomask;
|
||||
const unsigned int lo = v & ((1 << lobits) - 1);
|
||||
|
||||
*type = (v >> lobits) & 3;
|
||||
return lo;
|
||||
}
|
||||
|
||||
static int get_compacted_la_distance(unsigned int lclusterbits,
|
||||
static int get_compacted_la_distance(unsigned int lobits,
|
||||
unsigned int encodebits,
|
||||
unsigned int vcnt, u8 *in, int i)
|
||||
{
|
||||
const unsigned int lomask = (1 << lclusterbits) - 1;
|
||||
unsigned int lo, d1 = 0;
|
||||
u8 type;
|
||||
|
||||
DBG_BUGON(i >= vcnt);
|
||||
|
||||
do {
|
||||
lo = decode_compactedbits(lclusterbits, lomask,
|
||||
in, encodebits * i, &type);
|
||||
lo = decode_compactedbits(lobits, in, encodebits * i, &type);
|
||||
|
||||
if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
|
||||
return d1;
|
||||
@ -123,15 +120,14 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||
{
|
||||
struct erofs_inode *const vi = EROFS_I(m->inode);
|
||||
const unsigned int lclusterbits = vi->z_logical_clusterbits;
|
||||
const unsigned int lomask = (1 << lclusterbits) - 1;
|
||||
unsigned int vcnt, base, lo, encodebits, nblk, eofs;
|
||||
unsigned int vcnt, base, lo, lobits, encodebits, nblk, eofs;
|
||||
int i;
|
||||
u8 *in, type;
|
||||
bool big_pcluster;
|
||||
|
||||
if (1 << amortizedshift == 4 && lclusterbits <= 14)
|
||||
vcnt = 2;
|
||||
else if (1 << amortizedshift == 2 && lclusterbits == 12)
|
||||
else if (1 << amortizedshift == 2 && lclusterbits <= 12)
|
||||
vcnt = 16;
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
@ -140,6 +136,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||
m->nextpackoff = round_down(pos, vcnt << amortizedshift) +
|
||||
(vcnt << amortizedshift);
|
||||
big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1;
|
||||
lobits = max(lclusterbits, ilog2(Z_EROFS_LI_D0_CBLKCNT) + 1U);
|
||||
encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt;
|
||||
eofs = erofs_blkoff(m->inode->i_sb, pos);
|
||||
base = round_down(eofs, vcnt << amortizedshift);
|
||||
@ -147,15 +144,14 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||
|
||||
i = (eofs - base) >> amortizedshift;
|
||||
|
||||
lo = decode_compactedbits(lclusterbits, lomask,
|
||||
in, encodebits * i, &type);
|
||||
lo = decode_compactedbits(lobits, in, encodebits * i, &type);
|
||||
m->type = type;
|
||||
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
||||
m->clusterofs = 1 << lclusterbits;
|
||||
|
||||
/* figure out lookahead_distance: delta[1] if needed */
|
||||
if (lookahead)
|
||||
m->delta[1] = get_compacted_la_distance(lclusterbits,
|
||||
m->delta[1] = get_compacted_la_distance(lobits,
|
||||
encodebits, vcnt, in, i);
|
||||
if (lo & Z_EROFS_LI_D0_CBLKCNT) {
|
||||
if (!big_pcluster) {
|
||||
@ -174,8 +170,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||
* of which lo saves delta[1] rather than delta[0].
|
||||
* Hence, get delta[0] by the previous lcluster indirectly.
|
||||
*/
|
||||
lo = decode_compactedbits(lclusterbits, lomask,
|
||||
in, encodebits * (i - 1), &type);
|
||||
lo = decode_compactedbits(lobits, in,
|
||||
encodebits * (i - 1), &type);
|
||||
if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
|
||||
lo = 0;
|
||||
else if (lo & Z_EROFS_LI_D0_CBLKCNT)
|
||||
@ -190,8 +186,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||
nblk = 1;
|
||||
while (i > 0) {
|
||||
--i;
|
||||
lo = decode_compactedbits(lclusterbits, lomask,
|
||||
in, encodebits * i, &type);
|
||||
lo = decode_compactedbits(lobits, in,
|
||||
encodebits * i, &type);
|
||||
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD)
|
||||
i -= lo;
|
||||
|
||||
@ -202,8 +198,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||
nblk = 0;
|
||||
while (i > 0) {
|
||||
--i;
|
||||
lo = decode_compactedbits(lclusterbits, lomask,
|
||||
in, encodebits * i, &type);
|
||||
lo = decode_compactedbits(lobits, in,
|
||||
encodebits * i, &type);
|
||||
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
||||
if (lo & Z_EROFS_LI_D0_CBLKCNT) {
|
||||
--i;
|
||||
|
Loading…
Reference in New Issue
Block a user