Commit 5c40d2e9 authored by Gao Xiang's avatar Gao Xiang
Browse files

erofs: clean up encoded map flags



- Remove EROFS_MAP_ENCODED since it was always set together with
  EROFS_MAP_MAPPED for compressed extents and checked redundantly;

- Replace the EROFS_MAP_FULL_MAPPED flag with the opposite
  EROFS_MAP_PARTIAL_MAPPED flag so that extents are implicitly
  fully mapped initially to simplify the logic;

- Make fragment extents independent of EROFS_MAP_MAPPED since
  they are not directly allocated on disk; thus fragment extents
  are no longer twisted with mapped extents.

Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent 21e161de
Loading
Loading
Loading
Loading
+11 −12
Original line number Diff line number Diff line
@@ -360,20 +360,19 @@ static inline struct folio *erofs_grab_folio_nowait(struct address_space *as,
			readahead_gfp_mask(as) & ~__GFP_RECLAIM);
}

/* Has a disk mapping */
/* Allocated on disk at @m_pa (e.g. NOT a fragment extent) */
#define EROFS_MAP_MAPPED		0x0001
/* Located in metadata (could be copied from bd_inode) */
#define EROFS_MAP_META			0x0002
/* The extent is encoded */
#define EROFS_MAP_ENCODED	0x0004
/* The length of extent is full */
#define EROFS_MAP_FULL_MAPPED	0x0008
/* @m_llen may be truncated by the runtime compared to the on-disk record */
#define EROFS_MAP_PARTIAL_MAPPED	0x0004
/* The on-disk @m_llen may cover only part of the encoded data */
#define EROFS_MAP_PARTIAL_REF		0x0008
/* Located in the special packed inode */
#define __EROFS_MAP_FRAGMENT	0x0010
/* The extent refers to partial decompressed data */
#define EROFS_MAP_PARTIAL_REF	0x0020

#define EROFS_MAP_FRAGMENT	(EROFS_MAP_MAPPED | __EROFS_MAP_FRAGMENT)
#define EROFS_MAP_FRAGMENT		0x0010
/* The encoded on-disk data will be fully handled (decompressed) */
#define EROFS_MAP_FULL(f)	(!((f) & (EROFS_MAP_PARTIAL_MAPPED | \
					  EROFS_MAP_PARTIAL_REF)))

struct erofs_map_blocks {
	struct erofs_buf buf;
+9 −10
Original line number Diff line number Diff line
@@ -520,7 +520,7 @@ static bool z_erofs_should_alloc_cache(struct z_erofs_frontend *fe)
	if (cachestrategy <= EROFS_ZIP_CACHE_DISABLED)
		return false;

	if (!(fe->map.m_flags & EROFS_MAP_FULL_MAPPED))
	if (fe->map.m_flags & EROFS_MAP_PARTIAL_MAPPED)
		return true;

	if (cachestrategy >= EROFS_ZIP_CACHE_READAROUND &&
@@ -1033,10 +1033,7 @@ static int z_erofs_scan_folio(struct z_erofs_frontend *f,
		/* bump split parts first to avoid several separate cases */
		++split;

		if (!(map->m_flags & EROFS_MAP_MAPPED)) {
			folio_zero_segment(folio, cur, end);
			tight = false;
		} else if (map->m_flags & __EROFS_MAP_FRAGMENT) {
		if (map->m_flags & EROFS_MAP_FRAGMENT) {
			erofs_off_t fpos = offset + cur - map->m_la;

			err = z_erofs_read_fragment(inode->i_sb, folio, cur,
@@ -1045,6 +1042,9 @@ static int z_erofs_scan_folio(struct z_erofs_frontend *f,
			if (err)
				break;
			tight = false;
		} else if (!(map->m_flags & EROFS_MAP_MAPPED)) {
			folio_zero_segment(folio, cur, end);
			tight = false;
		} else {
			if (!f->pcl) {
				err = z_erofs_pcluster_begin(f);
@@ -1080,14 +1080,13 @@ static int z_erofs_scan_folio(struct z_erofs_frontend *f,
				f->pcl->length = offset + end - map->m_la;
				f->pcl->pageofs_out = map->m_la & ~PAGE_MASK;
			}
			if ((map->m_flags & EROFS_MAP_FULL_MAPPED) &&
			    !(map->m_flags & EROFS_MAP_PARTIAL_REF) &&
			if (EROFS_MAP_FULL(map->m_flags) &&
			    f->pcl->length == map->m_llen)
				f->pcl->partial = false;
		}
		/* shorten the remaining extent to update progress */
		map->m_llen = offset + cur - map->m_la;
		map->m_flags &= ~EROFS_MAP_FULL_MAPPED;
		map->m_flags |= EROFS_MAP_PARTIAL_MAPPED;
		if (cur <= pgs) {
			split = cur < pgs;
			tight = (bs == PAGE_SIZE);
@@ -1841,7 +1840,7 @@ static void z_erofs_pcluster_readmore(struct z_erofs_frontend *f,
		map->m_la = end;
		err = z_erofs_map_blocks_iter(inode, map,
					      EROFS_GET_BLOCKS_READMORE);
		if (err || !(map->m_flags & EROFS_MAP_ENCODED))
		if (err || !(map->m_flags & EROFS_MAP_MAPPED))
			return;

		/* expand ra for the trailing edge if readahead */
@@ -1853,7 +1852,7 @@ static void z_erofs_pcluster_readmore(struct z_erofs_frontend *f,
		end = round_up(end, PAGE_SIZE);
	} else {
		end = round_up(map->m_la, PAGE_SIZE);
		if (!(map->m_flags & EROFS_MAP_ENCODED) || !map->m_llen)
		if (!(map->m_flags & EROFS_MAP_MAPPED) || !map->m_llen)
			return;
	}

+10 −9
Original line number Diff line number Diff line
@@ -419,7 +419,7 @@ static int z_erofs_map_blocks_fo(struct inode *inode,

	if ((flags & EROFS_GET_BLOCKS_FINDTAIL) && ztailpacking)
		vi->z_fragmentoff = m.nextpackoff;
	map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_ENCODED;
	map->m_flags = EROFS_MAP_MAPPED | EROFS_MAP_PARTIAL_MAPPED;
	end = (m.lcn + 1ULL) << lclusterbits;

	if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD && endoff >= m.clusterofs) {
@@ -435,7 +435,7 @@ static int z_erofs_map_blocks_fo(struct inode *inode,
	} else {
		if (m.type != Z_EROFS_LCLUSTER_TYPE_NONHEAD) {
			end = (m.lcn << lclusterbits) | m.clusterofs;
			map->m_flags |= EROFS_MAP_FULL_MAPPED;
			map->m_flags &= ~EROFS_MAP_PARTIAL_MAPPED;
			m.delta[0] = 1;
		}
		/* get the corresponding first chunk */
@@ -496,7 +496,7 @@ static int z_erofs_map_blocks_fo(struct inode *inode,
	      map->m_llen >= i_blocksize(inode))) {
		err = z_erofs_get_extent_decompressedlen(&m);
		if (!err)
			map->m_flags |= EROFS_MAP_FULL_MAPPED;
			map->m_flags &= ~EROFS_MAP_PARTIAL_MAPPED;
	}

unmap_out:
@@ -594,8 +594,7 @@ static int z_erofs_map_blocks_ext(struct inode *inode,
			if (recsz > offsetof(struct z_erofs_extent, pstart_lo))
				vi->z_fragmentoff |= map->m_pa << 32;
		} else if (map->m_plen & Z_EROFS_EXTENT_PLEN_MASK) {
			map->m_flags |= EROFS_MAP_MAPPED |
				EROFS_MAP_FULL_MAPPED | EROFS_MAP_ENCODED;
			map->m_flags |= EROFS_MAP_MAPPED;
			fmt = map->m_plen >> Z_EROFS_EXTENT_PLEN_FMT_BIT;
			if (map->m_plen & Z_EROFS_EXTENT_PLEN_PARTIAL)
				map->m_flags |= EROFS_MAP_PARTIAL_REF;
@@ -714,7 +713,7 @@ static int z_erofs_map_sanity_check(struct inode *inode,
	struct erofs_sb_info *sbi = EROFS_I_SB(inode);
	u64 pend;

	if (!(map->m_flags & EROFS_MAP_ENCODED))
	if (!(map->m_flags & EROFS_MAP_MAPPED))
		return 0;
	if (unlikely(map->m_algorithmformat >= Z_EROFS_COMPRESSION_RUNTIME_MAX)) {
		erofs_err(inode->i_sb, "unknown algorithm %d @ pos %llu for nid %llu, please upgrade kernel",
@@ -781,10 +780,12 @@ static int z_erofs_iomap_begin_report(struct inode *inode, loff_t offset,
	iomap->bdev = inode->i_sb->s_bdev;
	iomap->offset = map.m_la;
	iomap->length = map.m_llen;
	if (map.m_flags & EROFS_MAP_MAPPED) {
	if (map.m_flags & EROFS_MAP_FRAGMENT) {
		iomap->type = IOMAP_MAPPED;
		iomap->addr = map.m_flags & __EROFS_MAP_FRAGMENT ?
			      IOMAP_NULL_ADDR : map.m_pa;
		iomap->addr = IOMAP_NULL_ADDR;
	} else if (map.m_flags & EROFS_MAP_MAPPED) {
		iomap->type = IOMAP_MAPPED;
		iomap->addr = map.m_pa;
	} else {
		iomap->type = IOMAP_HOLE;
		iomap->addr = IOMAP_NULL_ADDR;
+3 −4
Original line number Diff line number Diff line
@@ -26,10 +26,9 @@ struct erofs_map_blocks;
#define show_mflags(flags) __print_flags(flags, "",	\
	{ EROFS_MAP_MAPPED,		"M" },		\
	{ EROFS_MAP_META,		"I" },		\
	{ EROFS_MAP_ENCODED,		"E" },		\
	{ EROFS_MAP_FULL_MAPPED,	"F" },		\
	{ EROFS_MAP_FRAGMENT,		"R" },		\
	{ EROFS_MAP_PARTIAL_REF,	"P" })
	{ EROFS_MAP_PARTIAL_MAPPED,	"T" },		\
	{ EROFS_MAP_PARTIAL_REF,	"P" },		\
	{ EROFS_MAP_FRAGMENT,		"R" })

TRACE_EVENT(erofs_lookup,