Commit ab474fcc authored by Gao Xiang's avatar Gao Xiang

erofs: clean up z_erofs_extent_lookback

Avoid the unnecessary tail recursion since it can be converted into
a loop directly in order to prevent potential stack overflow.

It's a pretty straightforward conversion.

Link: https://lore.kernel.org/r/20220310182743.102365-1-hsiangkao@linux.alibaba.comReviewed-by: default avatarYue Hu <huyue2@coolpad.com>
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent d467e980
...@@ -431,48 +431,47 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m, ...@@ -431,48 +431,47 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
unsigned int lookback_distance) unsigned int lookback_distance)
{ {
struct erofs_inode *const vi = EROFS_I(m->inode); struct erofs_inode *const vi = EROFS_I(m->inode);
struct erofs_map_blocks *const map = m->map;
const unsigned int lclusterbits = vi->z_logical_clusterbits; const unsigned int lclusterbits = vi->z_logical_clusterbits;
unsigned long lcn = m->lcn;
int err;
if (lcn < lookback_distance) { while (m->lcn >= lookback_distance) {
erofs_err(m->inode->i_sb, unsigned long lcn = m->lcn - lookback_distance;
"bogus lookback distance @ nid %llu", vi->nid); int err;
DBG_BUGON(1);
return -EFSCORRUPTED;
}
/* load extent head logical cluster if needed */ /* load extent head logical cluster if needed */
lcn -= lookback_distance; err = z_erofs_load_cluster_from_disk(m, lcn, false);
err = z_erofs_load_cluster_from_disk(m, lcn, false); if (err)
if (err) return err;
return err;
switch (m->type) { switch (m->type) {
case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD: case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
if (!m->delta[0]) { if (!m->delta[0]) {
erofs_err(m->inode->i_sb,
"invalid lookback distance 0 @ nid %llu",
vi->nid);
DBG_BUGON(1);
return -EFSCORRUPTED;
}
lookback_distance = m->delta[0];
continue;
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2:
m->headtype = m->type;
m->map->m_la = (lcn << lclusterbits) | m->clusterofs;
return 0;
default:
erofs_err(m->inode->i_sb, erofs_err(m->inode->i_sb,
"invalid lookback distance 0 @ nid %llu", "unknown type %u @ lcn %lu of nid %llu",
vi->nid); m->type, lcn, vi->nid);
DBG_BUGON(1); DBG_BUGON(1);
return -EFSCORRUPTED; return -EOPNOTSUPP;
} }
return z_erofs_extent_lookback(m, m->delta[0]);
case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD1:
case Z_EROFS_VLE_CLUSTER_TYPE_HEAD2:
m->headtype = m->type;
map->m_la = (lcn << lclusterbits) | m->clusterofs;
break;
default:
erofs_err(m->inode->i_sb,
"unknown type %u @ lcn %lu of nid %llu",
m->type, lcn, vi->nid);
DBG_BUGON(1);
return -EOPNOTSUPP;
} }
return 0;
erofs_err(m->inode->i_sb, "bogus lookback distance @ nid %llu",
vi->nid);
DBG_BUGON(1);
return -EFSCORRUPTED;
} }
static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m, static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment