Source kernel commit: 999f2f9a63f475192d837a2b8595eb0962984d21 Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com> --- lib/zmap.c | 158 ++++++++++++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 81 deletions(-)
diff --git a/lib/zmap.c b/lib/zmap.c index f1cdc66..74c0033 100644 --- a/lib/zmap.c +++ b/lib/zmap.c @@ -10,10 +10,6 @@ #include "erofs/internal.h" #include "erofs/print.h" -static int z_erofs_do_map_blocks(struct erofs_inode *vi, - struct erofs_map_blocks *map, - int flags); - int z_erofs_fill_inode(struct erofs_inode *vi) { struct erofs_sb_info *sbi = vi->sbi; @@ -31,83 +27,6 @@ int z_erofs_fill_inode(struct erofs_inode *vi) return 0; } -static int z_erofs_fill_inode_lazy(struct erofs_inode *vi) -{ - int ret; - erofs_off_t pos; - struct z_erofs_map_header *h; - char buf[sizeof(struct z_erofs_map_header)]; - struct erofs_sb_info *sbi = vi->sbi; - - if (vi->flags & EROFS_I_Z_INITED) - return 0; - - pos = round_up(erofs_iloc(vi) + vi->inode_isize + vi->xattr_isize, 8); - ret = erofs_dev_read(sbi, 0, buf, pos, sizeof(buf)); - if (ret < 0) - return -EIO; - - h = (struct z_erofs_map_header *)buf; - /* - * if the highest bit of the 8-byte map header is set, the whole file - * is stored in the packed inode. The rest bits keeps z_fragmentoff. - */ - if (h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT) { - vi->z_advise = Z_EROFS_ADVISE_FRAGMENT_PCLUSTER; - vi->fragmentoff = le64_to_cpu(*(__le64 *)h) ^ (1ULL << 63); - vi->z_tailextent_headlcn = 0; - goto out; - } - - vi->z_advise = le16_to_cpu(h->h_advise); - vi->z_algorithmtype[0] = h->h_algorithmtype & 15; - vi->z_algorithmtype[1] = h->h_algorithmtype >> 4; - - if (vi->z_algorithmtype[0] >= Z_EROFS_COMPRESSION_MAX) { - erofs_err("unknown compression format %u for nid %llu", - vi->z_algorithmtype[0], (unsigned long long)vi->nid); - return -EOPNOTSUPP; - } - - vi->z_logical_clusterbits = sbi->blkszbits + (h->h_clusterbits & 7); - if (vi->datalayout == EROFS_INODE_COMPRESSED_COMPACT && - !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ - !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { - erofs_err("big pcluster head1/2 of compact indexes should be consistent for nid %llu", - vi->nid * 1ULL); - return -EFSCORRUPTED; - } - - if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) { - struct erofs_map_blocks map = { .index = UINT_MAX }; - - vi->idata_size = le16_to_cpu(h->h_idata_size); - ret = z_erofs_do_map_blocks(vi, &map, - EROFS_GET_BLOCKS_FINDTAIL); - if (!map.m_plen || - erofs_blkoff(sbi, map.m_pa) + map.m_plen > erofs_blksiz(sbi)) { - erofs_err("invalid tail-packing pclustersize %llu", - map.m_plen | 0ULL); - return -EFSCORRUPTED; - } - if (ret < 0) - return ret; - } - if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER && - !(h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT)) { - struct erofs_map_blocks map = { .index = UINT_MAX }; - - vi->fragmentoff = le32_to_cpu(h->h_fragmentoff); - ret = z_erofs_do_map_blocks(vi, &map, - EROFS_GET_BLOCKS_FINDTAIL); - if (ret < 0) - return ret; - } -out: - vi->flags |= EROFS_I_Z_INITED; - return 0; -} - struct z_erofs_maprecorder { struct erofs_inode *inode; struct erofs_map_blocks *map; @@ -668,6 +587,83 @@ out: return err; } +static int z_erofs_fill_inode_lazy(struct erofs_inode *vi) +{ + int ret; + erofs_off_t pos; + struct z_erofs_map_header *h; + char buf[sizeof(struct z_erofs_map_header)]; + struct erofs_sb_info *sbi = vi->sbi; + + if (vi->flags & EROFS_I_Z_INITED) + return 0; + + pos = round_up(erofs_iloc(vi) + vi->inode_isize + vi->xattr_isize, 8); + ret = erofs_dev_read(sbi, 0, buf, pos, sizeof(buf)); + if (ret < 0) + return -EIO; + + h = (struct z_erofs_map_header *)buf; + /* + * if the highest bit of the 8-byte map header is set, the whole file + * is stored in the packed inode. The rest bits keeps z_fragmentoff. + */ + if (h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT) { + vi->z_advise = Z_EROFS_ADVISE_FRAGMENT_PCLUSTER; + vi->fragmentoff = le64_to_cpu(*(__le64 *)h) ^ (1ULL << 63); + vi->z_tailextent_headlcn = 0; + goto out; + } + + vi->z_advise = le16_to_cpu(h->h_advise); + vi->z_algorithmtype[0] = h->h_algorithmtype & 15; + vi->z_algorithmtype[1] = h->h_algorithmtype >> 4; + + if (vi->z_algorithmtype[0] >= Z_EROFS_COMPRESSION_MAX) { + erofs_err("unknown compression format %u for nid %llu", + vi->z_algorithmtype[0], (unsigned long long)vi->nid); + return -EOPNOTSUPP; + } + + vi->z_logical_clusterbits = sbi->blkszbits + (h->h_clusterbits & 7); + if (vi->datalayout == EROFS_INODE_COMPRESSED_COMPACT && + !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_1) ^ + !(vi->z_advise & Z_EROFS_ADVISE_BIG_PCLUSTER_2)) { + erofs_err("big pcluster head1/2 of compact indexes should be consistent for nid %llu", + vi->nid * 1ULL); + return -EFSCORRUPTED; + } + + if (vi->z_advise & Z_EROFS_ADVISE_INLINE_PCLUSTER) { + struct erofs_map_blocks map = { .index = UINT_MAX }; + + vi->idata_size = le16_to_cpu(h->h_idata_size); + ret = z_erofs_do_map_blocks(vi, &map, + EROFS_GET_BLOCKS_FINDTAIL); + if (!map.m_plen || + erofs_blkoff(sbi, map.m_pa) + map.m_plen > erofs_blksiz(sbi)) { + erofs_err("invalid tail-packing pclustersize %llu", + map.m_plen | 0ULL); + return -EFSCORRUPTED; + } + if (ret < 0) + return ret; + } + if (vi->z_advise & Z_EROFS_ADVISE_FRAGMENT_PCLUSTER && + !(h->h_clusterbits >> Z_EROFS_FRAGMENT_INODE_BIT)) { + struct erofs_map_blocks map = { .index = UINT_MAX }; + + vi->fragmentoff = le32_to_cpu(h->h_fragmentoff); + ret = z_erofs_do_map_blocks(vi, &map, + EROFS_GET_BLOCKS_FINDTAIL); + if (ret < 0) + return ret; + } +out: + vi->flags |= EROFS_I_Z_INITED; + return 0; +} + int z_erofs_map_blocks_iter(struct erofs_inode *vi, struct erofs_map_blocks *map, int flags) -- 2.43.5