From: Gao Xiang Date: Fri, 10 Apr 2026 08:48:37 +0000 (+0800) Subject: erofs: clean up encoded map flags X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5c40d2e9e3ce9e81d76773c68756e9b07cce802c;p=thirdparty%2Fkernel%2Flinux.git 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: Gao Xiang --- diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index a4f0a42cf8c38..4792490161ec9 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -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 */ -#define EROFS_MAP_MAPPED 0x0001 +/* 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 +#define EROFS_MAP_META 0x0002 +/* @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; diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index b566996a0d1a5..8a0b155119312 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -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; } diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index 30775502b56da..67f55b9b57af2 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -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; diff --git a/include/trace/events/erofs.h b/include/trace/events/erofs.h index def20d06507b1..cd0e3fd8c23f1 100644 --- a/include/trace/events/erofs.h +++ b/include/trace/events/erofs.h @@ -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,