erofs: fix 1 lcluster-sized pcluster for big pcluster
If the 1st NONHEAD lcluster of a pcluster isn't CBLKCNT lcluster type
rather than a HEAD or PLAIN type instead, which means its pclustersize
_must_ be 1 lcluster (since its uncompressed size < 2 lclusters),
as illustrated below:
HEAD HEAD / PLAIN lcluster type
____________ ____________
|_:__________|_________:__| file data (uncompressed)
. .
.____________.
|____________| pcluster data (compressed)
Such on-disk case was explained before [1] but missed to be handled
properly in the runtime implementation.
It can be observed if manually generating 1 lcluster-sized pcluster
with 2 lclusters (thus CBLKCNT doesn't exist.) Let's fix it now.
[1] https://lore.kernel.org/r/20210407043927.10623-1-xiang@kernel.org
Link: https://lore.kernel.org/r/20210510064715.29123-1-xiang@kernel.org
Fixes: cec6e93bea
("erofs: support parsing big pcluster compress indexes")
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Gao Xiang <xiang@kernel.org>
This commit is contained in:
parent
46f2e04484
commit
0852b6ca94
|
@ -450,14 +450,31 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
|
||||||
lcn = m->lcn + 1;
|
lcn = m->lcn + 1;
|
||||||
if (m->compressedlcs)
|
if (m->compressedlcs)
|
||||||
goto out;
|
goto out;
|
||||||
if (lcn == initial_lcn)
|
|
||||||
goto err_bonus_cblkcnt;
|
|
||||||
|
|
||||||
err = z_erofs_load_cluster_from_disk(m, lcn);
|
err = z_erofs_load_cluster_from_disk(m, lcn);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the 1st NONHEAD lcluster has already been handled initially w/o
|
||||||
|
* valid compressedlcs, which means at least it mustn't be CBLKCNT, or
|
||||||
|
* an internal implemenatation error is detected.
|
||||||
|
*
|
||||||
|
* The following code can also handle it properly anyway, but let's
|
||||||
|
* BUG_ON in the debugging mode only for developers to notice that.
|
||||||
|
*/
|
||||||
|
DBG_BUGON(lcn == initial_lcn &&
|
||||||
|
m->type == Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD);
|
||||||
|
|
||||||
switch (m->type) {
|
switch (m->type) {
|
||||||
|
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
|
||||||
|
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD:
|
||||||
|
/*
|
||||||
|
* if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
|
||||||
|
* rather than CBLKCNT, it's a 1 lcluster-sized pcluster.
|
||||||
|
*/
|
||||||
|
m->compressedlcs = 1;
|
||||||
|
break;
|
||||||
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
|
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
|
||||||
if (m->delta[0] != 1)
|
if (m->delta[0] != 1)
|
||||||
goto err_bonus_cblkcnt;
|
goto err_bonus_cblkcnt;
|
||||||
|
|
Loading…
Reference in New Issue