Commit 8f9530ae authored by Gao Xiang's avatar Gao Xiang
Browse files

erofs: refine z_erofs_get_extent_compressedlen()

 - Set `compressedblks = 1` directly for non-bigpcluster cases.  This
   simplifies the logic a bit since lcluster sizes larger than one block
   are unsupported and the details remain unclear.

 - For Z_EROFS_LCLUSTER_TYPE_PLAIN pclusters, avoid assuming
   `compressedblks = 1` by default.  Instead, check if
   Z_EROFS_ADVISE_BIG_PCLUSTER_2 is set.

It basically has no impact to existing valid images, but it's useful to
find the gap to prepare for large PLAIN pclusters.

Link: https://lore.kernel.org/r/20250123090109.973463-1-hsiangkao@linux.alibaba.com


Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent 6e2c2342
Loading
Loading
Loading
Loading
+16 −20
Original line number Diff line number Diff line
@@ -294,27 +294,23 @@ static int z_erofs_extent_lookback(struct z_erofs_maprecorder *m,
static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
					    unsigned int initial_lcn)
{
	struct super_block *sb = m->inode->i_sb;
	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;
	unsigned long lcn;
	struct inode *inode = m->inode;
	struct super_block *sb = inode->i_sb;
	struct erofs_inode *vi = EROFS_I(inode);
	bool bigpcl1 = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1;
	bool bigpcl2 = vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2;
	unsigned long lcn = m->lcn + 1;
	int err;

	DBG_BUGON(m->type != Z_EROFS_LCLUSTER_TYPE_PLAIN &&
		  m->type != Z_EROFS_LCLUSTER_TYPE_HEAD1 &&
		  m->type != Z_EROFS_LCLUSTER_TYPE_HEAD2);
	DBG_BUGON(m->type == Z_EROFS_LCLUSTER_TYPE_NONHEAD);
	DBG_BUGON(m->type != m->headtype);

	if (m->headtype == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
	    ((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD1) &&
	     !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1)) ||
	    ((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) &&
	     !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2))) {
		map->m_plen = 1ULL << lclusterbits;
		return 0;
	}
	lcn = m->lcn + 1;
	if ((m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD1 && !bigpcl1) ||
	    ((m->headtype == Z_EROFS_LCLUSTER_TYPE_PLAIN ||
	      m->headtype == Z_EROFS_LCLUSTER_TYPE_HEAD2) && !bigpcl2) ||
	    (lcn << vi->z_logical_clusterbits) >= inode->i_size)
		m->compressedblks = 1;

	if (m->compressedblks)
		goto out;

@@ -339,9 +335,9 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
	case Z_EROFS_LCLUSTER_TYPE_HEAD2:
		/*
		 * if the 1st NONHEAD lcluster is actually PLAIN or HEAD type
		 * rather than CBLKCNT, it's a 1 lcluster-sized pcluster.
		 * rather than CBLKCNT, it's a 1 block-sized pcluster.
		 */
		m->compressedblks = 1 << (lclusterbits - sb->s_blocksize_bits);
		m->compressedblks = 1;
		break;
	case Z_EROFS_LCLUSTER_TYPE_NONHEAD:
		if (m->delta[0] != 1)
@@ -356,7 +352,7 @@ static int z_erofs_get_extent_compressedlen(struct z_erofs_maprecorder *m,
		return -EFSCORRUPTED;
	}
out:
	map->m_plen = erofs_pos(sb, m->compressedblks);
	m->map->m_plen = erofs_pos(sb, m->compressedblks);
	return 0;
err_bonus_cblkcnt:
	erofs_err(sb, "bogus CBLKCNT @ lcn %lu of nid %llu", lcn, vi->nid);