Skip to content

Commit 8d2517a

Browse files
committed
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 <[email protected]> Reviewed-by: Chao Yu <[email protected]> Signed-off-by: Gao Xiang <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 54ed3fd commit 8d2517a

File tree

1 file changed

+14
-18
lines changed

1 file changed

+14
-18
lines changed

fs/erofs/zmap.c

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -82,29 +82,26 @@ static int z_erofs_load_full_lcluster(struct z_erofs_maprecorder *m,
8282
}
8383

8484
static unsigned int decode_compactedbits(unsigned int lobits,
85-
unsigned int lomask,
8685
u8 *in, unsigned int pos, u8 *type)
8786
{
8887
const unsigned int v = get_unaligned_le32(in + pos / 8) >> (pos & 7);
89-
const unsigned int lo = v & lomask;
88+
const unsigned int lo = v & ((1 << lobits) - 1);
9089

9190
*type = (v >> lobits) & 3;
9291
return lo;
9392
}
9493

95-
static int get_compacted_la_distance(unsigned int lclusterbits,
94+
static int get_compacted_la_distance(unsigned int lobits,
9695
unsigned int encodebits,
9796
unsigned int vcnt, u8 *in, int i)
9897
{
99-
const unsigned int lomask = (1 << lclusterbits) - 1;
10098
unsigned int lo, d1 = 0;
10199
u8 type;
102100

103101
DBG_BUGON(i >= vcnt);
104102

105103
do {
106-
lo = decode_compactedbits(lclusterbits, lomask,
107-
in, encodebits * i, &type);
104+
lo = decode_compactedbits(lobits, in, encodebits * i, &type);
108105

109106
if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
110107
return d1;
@@ -123,15 +120,14 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
123120
{
124121
struct erofs_inode *const vi = EROFS_I(m->inode);
125122
const unsigned int lclusterbits = vi->z_logical_clusterbits;
126-
const unsigned int lomask = (1 << lclusterbits) - 1;
127-
unsigned int vcnt, base, lo, encodebits, nblk, eofs;
123+
unsigned int vcnt, base, lo, lobits, encodebits, nblk, eofs;
128124
int i;
129125
u8 *in, type;
130126
bool big_pcluster;
131127

132128
if (1 << amortizedshift == 4 && lclusterbits <= 14)
133129
vcnt = 2;
134-
else if (1 << amortizedshift == 2 && lclusterbits == 12)
130+
else if (1 << amortizedshift == 2 && lclusterbits <= 12)
135131
vcnt = 16;
136132
else
137133
return -EOPNOTSUPP;
@@ -140,22 +136,22 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
140136
m->nextpackoff = round_down(pos, vcnt << amortizedshift) +
141137
(vcnt << amortizedshift);
142138
big_pcluster = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1;
139+
lobits = max(lclusterbits, ilog2(Z_EROFS_LI_D0_CBLKCNT) + 1U);
143140
encodebits = ((vcnt << amortizedshift) - sizeof(__le32)) * 8 / vcnt;
144141
eofs = erofs_blkoff(m->inode->i_sb, pos);
145142
base = round_down(eofs, vcnt << amortizedshift);
146143
in = m->kaddr + base;
147144

148145
i = (eofs - base) >> amortizedshift;
149146

150-
lo = decode_compactedbits(lclusterbits, lomask,
151-
in, encodebits * i, &type);
147+
lo = decode_compactedbits(lobits, in, encodebits * i, &type);
152148
m->type = type;
153149
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
154150
m->clusterofs = 1 << lclusterbits;
155151

156152
/* figure out lookahead_distance: delta[1] if needed */
157153
if (lookahead)
158-
m->delta[1] = get_compacted_la_distance(lclusterbits,
154+
m->delta[1] = get_compacted_la_distance(lobits,
159155
encodebits, vcnt, in, i);
160156
if (lo & Z_EROFS_LI_D0_CBLKCNT) {
161157
if (!big_pcluster) {
@@ -174,8 +170,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
174170
* of which lo saves delta[1] rather than delta[0].
175171
* Hence, get delta[0] by the previous lcluster indirectly.
176172
*/
177-
lo = decode_compactedbits(lclusterbits, lomask,
178-
in, encodebits * (i - 1), &type);
173+
lo = decode_compactedbits(lobits, in,
174+
encodebits * (i - 1), &type);
179175
if (type != Z_EROFS_LCLUSTER_TYPE_NONHEAD)
180176
lo = 0;
181177
else if (lo & Z_EROFS_LI_D0_CBLKCNT)
@@ -190,8 +186,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
190186
nblk = 1;
191187
while (i > 0) {
192188
--i;
193-
lo = decode_compactedbits(lclusterbits, lomask,
194-
in, encodebits * i, &type);
189+
lo = decode_compactedbits(lobits, in,
190+
encodebits * i, &type);
195191
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD)
196192
i -= lo;
197193

@@ -202,8 +198,8 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
202198
nblk = 0;
203199
while (i > 0) {
204200
--i;
205-
lo = decode_compactedbits(lclusterbits, lomask,
206-
in, encodebits * i, &type);
201+
lo = decode_compactedbits(lobits, in,
202+
encodebits * i, &type);
207203
if (type == Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
208204
if (lo & Z_EROFS_LI_D0_CBLKCNT) {
209205
--i;

0 commit comments

Comments
 (0)