mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 08:33:17 +02: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,
|
static unsigned int decode_compactedbits(unsigned int lobits,
|
||||||
unsigned int lomask,
|
|
||||||
u8 *in, unsigned int pos, u8 *type)
|
u8 *in, unsigned int pos, u8 *type)
|
||||||
{
|
{
|
||||||
const unsigned int v = get_unaligned_le32(in + pos / 8) >> (pos & 7);
|
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;
|
*type = (v >> lobits) & 3;
|
||||||
return lo;
|
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 encodebits,
|
||||||
unsigned int vcnt, u8 *in, int i)
|
unsigned int vcnt, u8 *in, int i)
|
||||||
{
|
{
|
||||||
const unsigned int lomask = (1 << lclusterbits) - 1;
|
|
||||||
unsigned int lo, d1 = 0;
|
unsigned int lo, d1 = 0;
|
||||||
u8 type;
|
u8 type;
|
||||||
|
|
||||||
DBG_BUGON(i >= vcnt);
|
DBG_BUGON(i >= vcnt);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
lo = decode_compactedbits(lclusterbits, lomask,
|
lo = decode_compactedbits(lobits, in, encodebits * i, &type);
|
||||||
in, encodebits * i, &type);
|
|
||||||
|
|
||||||
if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
|
if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
|
||||||
return d1;
|
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);
|
struct erofs_inode *const vi = EROFS_I(m->inode);
|
||||||
const unsigned int lclusterbits = vi->z_logical_clusterbits;
|
const unsigned int lclusterbits = vi->z_logical_clusterbits;
|
||||||
const unsigned int lomask = (1 << lclusterbits) - 1;
|
unsigned int vcnt, base, lo, lobits, encodebits, nblk, eofs;
|
||||||
unsigned int vcnt, base, lo, encodebits, nblk, eofs;
|
|
||||||
int i;
|
int i;
|
||||||
u8 *in, type;
|
u8 *in, type;
|
||||||
bool big_pcluster;
|
bool big_pcluster;
|
||||||
|
|
||||||
if (1 << amortizedshift == 4 && lclusterbits <= 14)
|
if (1 << amortizedshift == 4 && lclusterbits <= 14)
|
||||||
vcnt = 2;
|
vcnt = 2;
|
||||||
else if (1 << amortizedshift == 2 && lclusterbits == 12)
|
else if (1 << amortizedshift == 2 && lclusterbits <= 12)
|
||||||
vcnt = 16;
|
vcnt = 16;
|
||||||
else
|
else
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
@ -140,6 +136,7 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||||
m->nextpackoff = round_down(pos, vcnt << amortizedshift) +
|
m->nextpackoff = round_down(pos, vcnt << amortizedshift) +
|
||||||
(vcnt << amortizedshift);
|
(vcnt << amortizedshift);
|
||||||
big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1;
|
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;
|
encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt;
|
||||||
eofs = erofs_blkoff(m->inode->i_sb, pos);
|
eofs = erofs_blkoff(m->inode->i_sb, pos);
|
||||||
base = round_down(eofs, vcnt << amortizedshift);
|
base = round_down(eofs, vcnt << amortizedshift);
|
||||||
|
|
@ -147,15 +144,14 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||||
|
|
||||||
i = (eofs - base) >> amortizedshift;
|
i = (eofs - base) >> amortizedshift;
|
||||||
|
|
||||||
lo = decode_compactedbits(lclusterbits, lomask,
|
lo = decode_compactedbits(lobits, in, encodebits * i, &type);
|
||||||
in, encodebits * i, &type);
|
|
||||||
m->type = type;
|
m->type = type;
|
||||||
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
||||||
m->clusterofs = 1 << lclusterbits;
|
m->clusterofs = 1 << lclusterbits;
|
||||||
|
|
||||||
/* figure out lookahead_distance: delta[1] if needed */
|
/* figure out lookahead_distance: delta[1] if needed */
|
||||||
if (lookahead)
|
if (lookahead)
|
||||||
m->delta[1] = get_compacted_la_distance(lclusterbits,
|
m->delta[1] = get_compacted_la_distance(lobits,
|
||||||
encodebits, vcnt, in, i);
|
encodebits, vcnt, in, i);
|
||||||
if (lo & Z_EROFS_LI_D0_CBLKCNT) {
|
if (lo & Z_EROFS_LI_D0_CBLKCNT) {
|
||||||
if (!big_pcluster) {
|
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].
|
* of which lo saves delta[1] rather than delta[0].
|
||||||
* Hence, get delta[0] by the previous lcluster indirectly.
|
* Hence, get delta[0] by the previous lcluster indirectly.
|
||||||
*/
|
*/
|
||||||
lo = decode_compactedbits(lclusterbits, lomask,
|
lo = decode_compactedbits(lobits, in,
|
||||||
in, encodebits * (i - 1), &type);
|
encodebits * (i - 1), &type);
|
||||||
if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
|
if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
|
||||||
lo = 0;
|
lo = 0;
|
||||||
else if (lo & Z_EROFS_LI_D0_CBLKCNT)
|
else if (lo & Z_EROFS_LI_D0_CBLKCNT)
|
||||||
|
|
@ -190,8 +186,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||||
nblk = 1;
|
nblk = 1;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
--i;
|
--i;
|
||||||
lo = decode_compactedbits(lclusterbits, lomask,
|
lo = decode_compactedbits(lobits, in,
|
||||||
in, encodebits * i, &type);
|
encodebits * i, &type);
|
||||||
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD)
|
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD)
|
||||||
i -= lo;
|
i -= lo;
|
||||||
|
|
||||||
|
|
@ -202,8 +198,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
|
||||||
nblk = 0;
|
nblk = 0;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
--i;
|
--i;
|
||||||
lo = decode_compactedbits(lclusterbits, lomask,
|
lo = decode_compactedbits(lobits, in,
|
||||||
in, encodebits * i, &type);
|
encodebits * i, &type);
|
||||||
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
|
||||||
if (lo & Z_EROFS_LI_D0_CBLKCNT) {
|
if (lo & Z_EROFS_LI_D0_CBLKCNT) {
|
||||||
--i;
|
--i;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user