[PATCH v1 3/4] Make super block info struct a paramater instead of globals
Gao Xiang
xiang at kernel.org
Tue Nov 23 18:54:19 AEDT 2021
On Sat, Nov 20, 2021 at 09:39:20PM -0800, Kelvin Zhang wrote:
>
> Test: mkfs.erofs on system.img of
> aosp_cf_x86_64_phone-target_files-7731383.zip
> Make sure output is the same before/after this patch
>
> Signed-off-by: Kelvin Zhang <zhangkelvin at google.com>
Yeah, it'd be helpful if we have multiple sb instances.
Yet same as I suggested in [PATCH 1/4], it would be better to
make
struct erofs_inode {
..
struct erofs_sb_info *sbi;
...
};
So most functions don't need to pass in sbi... And inode -> sbi
can help multiple instance runtime as well.
Thanks,
Gao Xiang
> ---
> dump/main.c | 67 +++++++++++++++++++------------
> fsck/main.c | 61 +++++++++++++++++++----------
> fuse/dir.c | 5 ++-
> fuse/main.c | 7 ++--
> include/erofs/compress.h | 2 +
> include/erofs/decompress.h | 5 ++-
> include/erofs/inode.h | 3 +-
> include/erofs/internal.h | 26 ++++++++-----
> include/erofs/xattr.h | 2 +-
> lib/compress.c | 80 +++++++++++++++++++++++---------------
> lib/compressor.c | 7 +++-
> lib/compressor.h | 5 ++-
> lib/compressor_lz4.c | 6 ++-
> lib/compressor_lz4hc.c | 4 +-
> lib/config.c | 1 -
> lib/data.c | 36 ++++++++++-------
> lib/decompress.c | 12 +++---
> lib/inode.c | 60 ++++++++++++++++------------
> lib/namei.c | 40 ++++++++++++-------
> lib/xattr.c | 4 +-
> lib/zmap.c | 46 +++++++++++++---------
> mkfs/main.c | 63 ++++++++++++++++--------------
> 22 files changed, 332 insertions(+), 210 deletions(-)
>
> diff --git a/dump/main.c b/dump/main.c
> index 8d0dbd0..0ac97a0 100644
> --- a/dump/main.c
> +++ b/dump/main.c
> @@ -85,7 +85,10 @@ static struct erofsdump_feature feature_lists[] = {
> { false, EROFS_FEATURE_INCOMPAT_CHUNKED_FILE, "chunked_file" },
> };
>
> -static int erofs_read_dir(struct erofs_device fd, erofs_nid_t nid, erofs_nid_t parent_nid);
> +static int erofs_read_dir(
> + struct erofs_device fd,
> + struct erofs_sb_info *sbi,
> + erofs_nid_t nid, erofs_nid_t parent_nid);
> static inline int erofs_checkdirent(struct erofs_dirent *de,
> struct erofs_dirent *last_de,
> u32 maxsize, const char *dname);
> @@ -258,7 +261,9 @@ static inline int erofs_checkdirent(struct erofs_dirent *de,
> }
>
> static int erofs_read_dirent(
> - struct erofs_device erofs_dev, struct erofs_dirent *de,
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_dirent *de,
> erofs_nid_t nid, erofs_nid_t parent_nid,
> const char *dname)
> {
> @@ -268,7 +273,7 @@ static int erofs_read_dirent(
>
> stats.files++;
> stats.file_category_stat[de->file_type]++;
> - err = erofs_read_inode_from_disk(erofs_dev, &inode);
> + err = erofs_read_inode_from_disk(erofs_dev, sbi, &inode);
> if (err) {
> erofs_err("read file inode from disk failed!");
> return err;
> @@ -289,7 +294,7 @@ static int erofs_read_dirent(
>
> if ((de->file_type == EROFS_FT_DIR)
> && de->nid != nid && de->nid != parent_nid) {
> - err = erofs_read_dir(erofs_dev, de->nid, nid);
> + err = erofs_read_dir(erofs_dev, sbi, de->nid, nid);
> if (err) {
> erofs_err("parse dir nid %llu error occurred\n",
> de->nid);
> @@ -299,14 +304,17 @@ static int erofs_read_dirent(
> return 0;
> }
>
> -static int erofs_read_dir(struct erofs_device fd, erofs_nid_t nid, erofs_nid_t parent_nid)
> +static int erofs_read_dir(
> + struct erofs_device fd,
> + struct erofs_sb_info *sbi,
> + erofs_nid_t nid, erofs_nid_t parent_nid)
> {
> int err;
> erofs_off_t offset;
> char buf[EROFS_BLKSIZ];
> struct erofs_inode vi = { .nid = nid };
>
> - err = erofs_read_inode_from_disk(fd, &vi);
> + err = erofs_read_inode_from_disk(fd, sbi, &vi);
> if (err)
> return err;
>
> @@ -318,7 +326,7 @@ static int erofs_read_dir(struct erofs_device fd, erofs_nid_t nid, erofs_nid_t p
> struct erofs_dirent *end;
> unsigned int nameoff;
>
> - err = erofs_pread(fd, &vi, buf, maxsize, offset);
> + err = erofs_pread(fd, sbi, &vi, buf, maxsize, offset);
> if (err)
> return err;
>
> @@ -338,7 +346,7 @@ static int erofs_read_dir(struct erofs_device fd, erofs_nid_t nid, erofs_nid_t p
> ret = erofs_checkdirent(de, end, maxsize, dname);
> if (ret < 0)
> return ret;
> - ret = erofs_read_dirent(fd, de, nid, parent_nid, dname);
> + ret = erofs_read_dirent(fd, sbi, de, nid, parent_nid, dname);
> if (ret < 0)
> return ret;
> ++de;
> @@ -348,7 +356,10 @@ static int erofs_read_dir(struct erofs_device fd, erofs_nid_t nid, erofs_nid_t p
> return 0;
> }
>
> -static int erofs_get_pathname(struct erofs_device fd, erofs_nid_t nid, erofs_nid_t parent_nid,
> +static int erofs_get_pathname(
> + struct erofs_device fd,
> + struct erofs_sb_info *sbi,
> + erofs_nid_t nid, erofs_nid_t parent_nid,
> erofs_nid_t target, char *path, unsigned int pos)
> {
> int err;
> @@ -357,10 +368,10 @@ static int erofs_get_pathname(struct erofs_device fd, erofs_nid_t nid, erofs_nid
> struct erofs_inode inode = { .nid = nid };
>
> path[pos++] = '/';
> - if (target == sbi.root_nid)
> + if (target == sbi->root_nid)
> return 0;
>
> - err = erofs_read_inode_from_disk(fd, &inode);
> + err = erofs_read_inode_from_disk(fd, sbi, &inode);
> if (err) {
> erofs_err("read inode failed @ nid %llu", nid | 0ULL);
> return err;
> @@ -374,7 +385,7 @@ static int erofs_get_pathname(struct erofs_device fd, erofs_nid_t nid, erofs_nid
> struct erofs_dirent *end;
> unsigned int nameoff;
>
> - err = erofs_pread(fd, &inode, buf, maxsize, offset);
> + err = erofs_pread(fd, sbi, &inode, buf, maxsize, offset);
> if (err)
> return err;
>
> @@ -400,7 +411,7 @@ static int erofs_get_pathname(struct erofs_device fd, erofs_nid_t nid, erofs_nid
> de->nid != parent_nid &&
> de->nid != nid) {
> memcpy(path + pos, dname, len);
> - err = erofs_get_pathname(fd, de->nid, nid,
> + err = erofs_get_pathname(fd, sbi, de->nid, nid,
> target, path, pos + len);
> if (!err)
> return 0;
> @@ -415,16 +426,19 @@ static int erofs_get_pathname(struct erofs_device fd, erofs_nid_t nid, erofs_nid
>
> static int erofsdump_map_blocks(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_inode *inode,
> struct erofs_map_blocks *map,
> int flags)
> {
> if (erofs_inode_is_data_compressed(inode->datalayout))
> - return z_erofs_map_blocks_iter(erofs_dev, inode, map, flags);
> - return erofs_map_blocks(erofs_dev, inode, map, flags);
> + return z_erofs_map_blocks_iter(erofs_dev, sbi, inode, map, flags);
> + return erofs_map_blocks(erofs_dev, sbi, inode, map, flags);
> }
>
> -static void erofsdump_show_fileinfo(struct erofs_device fd, bool show_extent)
> +static void erofsdump_show_fileinfo(
> + struct erofs_device fd,
> + struct erofs_sb_info *sbi, bool show_extent)
> {
> int err, i;
> erofs_off_t size;
> @@ -439,7 +453,7 @@ static void erofsdump_show_fileinfo(struct erofs_device fd, bool show_extent)
> .m_la = 0,
> };
>
> - err = erofs_read_inode_from_disk(fd, &inode);
> + err = erofs_read_inode_from_disk(fd, sbi, &inode);
> if (err) {
> erofs_err("read inode failed @ nid %llu", inode.nid | 0ULL);
> return;
> @@ -451,7 +465,7 @@ static void erofsdump_show_fileinfo(struct erofs_device fd, bool show_extent)
> return;
> }
>
> - err = erofs_get_pathname(fd, sbi.root_nid, sbi.root_nid,
> + err = erofs_get_pathname(fd, sbi, sbi->root_nid, sbi->root_nid,
> inode.nid, path, 0);
> if (err < 0) {
> erofs_err("file path not found @ nid %llu", inode.nid | 0ULL);
> @@ -484,7 +498,7 @@ static void erofsdump_show_fileinfo(struct erofs_device fd, bool show_extent)
>
> fprintf(stdout, "\n Ext: logical offset | length : physical offset | length \n");
> while (map.m_la < inode.i_size) {
> - err = erofsdump_map_blocks(fd, &inode, &map,
> + err = erofsdump_map_blocks(fd, sbi, &inode, &map,
> EROFS_GET_BLOCKS_FIEMAP);
> if (err) {
> erofs_err("get file blocks range failed");
> @@ -584,11 +598,13 @@ static void erofsdump_file_statistic(void)
> stats.compress_rate);
> }
>
> -static void erofsdump_print_statistic(struct erofs_device fd)
> +static void erofsdump_print_statistic(
> + struct erofs_device fd,
> + struct erofs_sb_info *sbi)
> {
> int err;
>
> - err = erofs_read_dir(fd, sbi.root_nid, sbi.root_nid);
> + err = erofs_read_dir(fd, sbi, sbi->root_nid, sbi->root_nid);
> if (err) {
> erofs_err("read dir failed");
> return;
> @@ -604,7 +620,7 @@ static void erofsdump_print_statistic(struct erofs_device fd)
> erofsdump_filetype_distribution(file_types, OTHERFILETYPE);
> }
>
> -static void erofsdump_show_superblock(void)
> +static void erofsdump_show_superblock(struct erofs_sb_info sbi)
> {
> time_t time = sbi.build_time;
> char uuid_str[37] = "not available";
> @@ -643,6 +659,7 @@ int main(int argc, char **argv)
> {
> int err;
> struct erofs_device erofs_dev;
> + struct erofs_sb_info sbi;
>
> erofs_init_global_configure();
> err = erofsdump_parse_options_cfg(argc, argv);
> @@ -669,10 +686,10 @@ int main(int argc, char **argv)
> dumpcfg.totalshow = 1;
> }
> if (dumpcfg.show_superblock)
> - erofsdump_show_superblock();
> + erofsdump_show_superblock(sbi);
>
> if (dumpcfg.show_statistics)
> - erofsdump_print_statistic(erofs_dev);
> + erofsdump_print_statistic(erofs_dev, &sbi);
>
> if (dumpcfg.show_extent && !dumpcfg.show_inode) {
> usage();
> @@ -680,7 +697,7 @@ int main(int argc, char **argv)
> }
>
> if (dumpcfg.show_inode)
> - erofsdump_show_fileinfo(erofs_dev, dumpcfg.show_extent);
> + erofsdump_show_fileinfo(erofs_dev, &sbi, dumpcfg.show_extent);
>
> exit:
> erofs_exit_global_configure();
> diff --git a/fsck/main.c b/fsck/main.c
> index b69333b..d6ce1a4 100644
> --- a/fsck/main.c
> +++ b/fsck/main.c
> @@ -11,7 +11,10 @@
> #include "erofs/io.h"
> #include "erofs/decompress.h"
>
> -static void erofs_check_inode(struct erofs_device devfd, erofs_nid_t pnid, erofs_nid_t nid);
> +static void erofs_check_inode(
> + struct erofs_device devfd,
> + struct erofs_sb_info *sbi,
> + erofs_nid_t pnid, erofs_nid_t nid);
>
> struct erofsfsck_cfg {
> bool corrupted;
> @@ -138,7 +141,10 @@ static bool check_special_dentry(struct erofs_dirent *de,
> return true;
> }
>
> -static int traverse_dirents(struct erofs_device devfd, erofs_nid_t pnid, erofs_nid_t nid,
> +static int traverse_dirents(
> + struct erofs_device devfd,
> + struct erofs_sb_info *sbi,
> + erofs_nid_t pnid, erofs_nid_t nid,
> void *dentry_blk, erofs_blk_t block,
> unsigned int next_nameoff, unsigned int maxsize)
> {
> @@ -212,7 +218,7 @@ static int traverse_dirents(struct erofs_device devfd, erofs_nid_t pnid, erofs_n
> goto out;
> }
> } else {
> - erofs_check_inode(devfd, nid, de->nid);
> + erofs_check_inode(devfd, sbi, nid, de->nid);
> }
>
> if (fsckcfg.corrupted) {
> @@ -236,7 +242,9 @@ out:
> }
>
> static int verify_uncompressed_inode(
> - struct erofs_device erofs_dev, struct erofs_inode *inode)
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode)
> {
> struct erofs_map_blocks map = {
> .index = UINT_MAX,
> @@ -247,7 +255,7 @@ static int verify_uncompressed_inode(
>
> while (ptr < inode->i_size) {
> map.m_la = ptr;
> - ret = erofs_map_blocks(erofs_dev, inode, &map, 0);
> + ret = erofs_map_blocks(erofs_dev, sbi, inode, &map, 0);
> if (ret)
> return ret;
>
> @@ -274,7 +282,10 @@ static int verify_uncompressed_inode(
> return 0;
> }
>
> -static int verify_compressed_inode(struct erofs_device erofs_dev, struct erofs_inode *inode)
> +static int verify_compressed_inode(
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode)
> {
> struct erofs_map_blocks map = {
> .index = UINT_MAX,
> @@ -288,7 +299,7 @@ static int verify_compressed_inode(struct erofs_device erofs_dev, struct erofs_i
> while (end > 0) {
> map.m_la = end - 1;
>
> - ret = z_erofs_map_blocks_iter(erofs_dev, inode, &map, 0);
> + ret = z_erofs_map_blocks_iter(erofs_dev, sbi, inode, &map, 0);
> if (ret)
> goto out;
>
> @@ -336,7 +347,7 @@ static int verify_compressed_inode(struct erofs_device erofs_dev, struct erofs_i
> .decodedlength = map.m_llen,
> .alg = algorithmformat,
> .partial_decoding = 0
> - });
> + }, sbi);
>
> if (ret < 0) {
> erofs_err("failed to decompress data of m_pa %" PRIu64 ", m_plen %" PRIu64 " @ nid %llu: %d",
> @@ -359,7 +370,10 @@ out:
> return ret < 0 ? ret : 0;
> }
>
> -static int erofs_verify_xattr(struct erofs_device erofs_dev, struct erofs_inode *inode)
> +static int erofs_verify_xattr(
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode)
> {
> unsigned int xattr_hdr_size = sizeof(struct erofs_xattr_ibody_header);
> unsigned int xattr_entry_size = sizeof(struct erofs_xattr_entry);
> @@ -384,7 +398,7 @@ static int erofs_verify_xattr(struct erofs_device erofs_dev, struct erofs_inode
> }
> }
>
> - addr = iloc(inode->nid) + inode->inode_isize;
> + addr = iloc(sbi, inode->nid) + inode->inode_isize;
> ret = dev_read(erofs_dev, buf, addr, xattr_hdr_size);
> if (ret < 0) {
> erofs_err("failed to read xattr header @ nid %llu: %d",
> @@ -437,7 +451,10 @@ out:
> return ret;
> }
>
> -static int erofs_verify_inode_data(struct erofs_device erofs_dev, struct erofs_inode *inode)
> +static int erofs_verify_inode_data(
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode)
> {
> int ret;
>
> @@ -448,11 +465,11 @@ static int erofs_verify_inode_data(struct erofs_device erofs_dev, struct erofs_i
> case EROFS_INODE_FLAT_PLAIN:
> case EROFS_INODE_FLAT_INLINE:
> case EROFS_INODE_CHUNK_BASED:
> - ret = verify_uncompressed_inode(erofs_dev, inode);
> + ret = verify_uncompressed_inode(erofs_dev, sbi, inode);
> break;
> case EROFS_INODE_FLAT_COMPRESSION_LEGACY:
> case EROFS_INODE_FLAT_COMPRESSION:
> - ret = verify_compressed_inode(erofs_dev, inode);
> + ret = verify_compressed_inode(erofs_dev, sbi, inode);
> break;
> default:
> ret = -EINVAL;
> @@ -466,7 +483,10 @@ static int erofs_verify_inode_data(struct erofs_device erofs_dev, struct erofs_i
> return ret;
> }
>
> -static void erofs_check_inode(struct erofs_device erofs_dev, erofs_nid_t pnid, erofs_nid_t nid)
> +static void erofs_check_inode(
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + erofs_nid_t pnid, erofs_nid_t nid)
> {
> int ret;
> struct erofs_inode inode;
> @@ -476,7 +496,7 @@ static void erofs_check_inode(struct erofs_device erofs_dev, erofs_nid_t pnid, e
> erofs_dbg("check inode: nid(%llu)", nid | 0ULL);
>
> inode.nid = nid;
> - ret = erofs_read_inode_from_disk(erofs_dev, &inode);
> + ret = erofs_read_inode_from_disk(erofs_dev, sbi, &inode);
> if (ret) {
> if (ret == -EIO)
> erofs_err("I/O error occurred when reading nid(%llu)",
> @@ -485,12 +505,12 @@ static void erofs_check_inode(struct erofs_device erofs_dev, erofs_nid_t pnid, e
> }
>
> /* verify xattr field */
> - ret = erofs_verify_xattr(erofs_dev,&inode);
> + ret = erofs_verify_xattr(erofs_dev, sbi, &inode);
> if (ret)
> goto out;
>
> /* verify data chunk layout */
> - ret = erofs_verify_inode_data(erofs_dev, &inode);
> + ret = erofs_verify_inode_data(erofs_dev, sbi, &inode);
> if (ret)
> goto out;
>
> @@ -506,7 +526,7 @@ static void erofs_check_inode(struct erofs_device erofs_dev, erofs_nid_t pnid, e
>
> unsigned int nameoff;
>
> - ret = erofs_pread(erofs_dev, &inode, buf, maxsize, offset);
> + ret = erofs_pread(erofs_dev, sbi, &inode, buf, maxsize, offset);
> if (ret) {
> erofs_err("I/O error occurred when reading dirents @ nid %llu, block %u: %d",
> nid | 0ULL, block, ret);
> @@ -522,7 +542,7 @@ static void erofs_check_inode(struct erofs_device erofs_dev, erofs_nid_t pnid, e
> goto out;
> }
>
> - ret = traverse_dirents(erofs_dev, pnid, nid, buf, block,
> + ret = traverse_dirents(erofs_dev, sbi, pnid, nid, buf, block,
> nameoff, maxsize);
> if (ret)
> goto out;
> @@ -538,6 +558,7 @@ int main(int argc, char **argv)
> {
> int err;
> struct erofs_device erofs_dev;
> + struct erofs_sb_info sbi;
>
> erofs_init_global_configure();
>
> @@ -571,7 +592,7 @@ int main(int argc, char **argv)
> goto exit;
> }
>
> - erofs_check_inode(erofs_dev, sbi.root_nid, sbi.root_nid);
> + erofs_check_inode(erofs_dev, &sbi, sbi.root_nid, sbi.root_nid);
>
> if (fsckcfg.corrupted) {
> erofs_err("Found some filesystem corruption");
> diff --git a/fuse/dir.c b/fuse/dir.c
> index 494c915..b7ff635 100644
> --- a/fuse/dir.c
> +++ b/fuse/dir.c
> @@ -10,6 +10,7 @@
>
> // defined in fuse/main.c
> extern struct erofs_device erofs_dev;
> +extern struct erofs_sb_info sbi;
>
> static int erofs_fill_dentries(struct erofs_inode *dir,
> fuse_fill_dir_t filler, void *buf,
> @@ -60,7 +61,7 @@ int erofsfuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
>
> erofs_dbg("readdir:%s offset=%llu", path, (long long)offset);
>
> - ret = erofs_ilookup(erofs_dev, path, &dir);
> + ret = erofs_ilookup(erofs_dev, &sbi, path, &dir);
> if (ret)
> return ret;
>
> @@ -79,7 +80,7 @@ int erofsfuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
>
> maxsize = min_t(unsigned int, EROFS_BLKSIZ,
> dir.i_size - pos);
> - ret = erofs_pread(erofs_dev, &dir, dblk, maxsize, pos);
> + ret = erofs_pread(erofs_dev, &sbi, &dir, dblk, maxsize, pos);
> if (ret)
> return ret;
>
> diff --git a/fuse/main.c b/fuse/main.c
> index b3e1a3d..37edf46 100644
> --- a/fuse/main.c
> +++ b/fuse/main.c
> @@ -14,6 +14,7 @@
> #include "erofs/io.h"
>
> struct erofs_device erofs_dev;
> +struct erofs_sb_info sbi;
>
> int erofsfuse_readdir(const char *path, void *buffer, fuse_fill_dir_t filler,
> off_t offset, struct fuse_file_info *fi);
> @@ -40,7 +41,7 @@ static int erofsfuse_getattr(const char *path, struct stat *stbuf)
> int ret;
>
> erofs_dbg("getattr(%s)", path);
> - ret = erofs_ilookup(erofs_dev, path, &vi);
> + ret = erofs_ilookup(erofs_dev, &sbi, path, &vi);
> if (ret)
> return -ENOENT;
>
> @@ -67,11 +68,11 @@ static int erofsfuse_read(const char *path, char *buffer,
>
> erofs_dbg("path:%s size=%zd offset=%llu", path, size, (long long)offset);
>
> - ret = erofs_ilookup(erofs_dev, path, &vi);
> + ret = erofs_ilookup(erofs_dev, &sbi, path, &vi);
> if (ret)
> return ret;
>
> - ret = erofs_pread(erofs_dev, &vi, buffer, size, offset);
> + ret = erofs_pread(erofs_dev, &sbi, &vi, buffer, size, offset);
> if (ret)
> return ret;
> if (offset >= vi.i_size)
> diff --git a/include/erofs/compress.h b/include/erofs/compress.h
> index 73834a7..813b8e0 100644
> --- a/include/erofs/compress.h
> +++ b/include/erofs/compress.h
> @@ -16,10 +16,12 @@
>
> int erofs_write_compressed_file(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_inode *inode);
>
> int z_erofs_compress_init(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_buffer_head *bh);
> int z_erofs_compress_exit(void);
>
> diff --git a/include/erofs/decompress.h b/include/erofs/decompress.h
> index 0ba2b08..4880bfd 100644
> --- a/include/erofs/decompress.h
> +++ b/include/erofs/decompress.h
> @@ -28,6 +28,9 @@ struct z_erofs_decompress_req {
> bool partial_decoding;
> };
>
> -int z_erofs_decompress(struct z_erofs_decompress_req *rq);
> +int z_erofs_decompress(
> + struct z_erofs_decompress_req *rq,
> + struct erofs_sb_info *sbi
> + );
>
> #endif
> diff --git a/include/erofs/inode.h b/include/erofs/inode.h
> index 5483d04..3b03482 100644
> --- a/include/erofs/inode.h
> +++ b/include/erofs/inode.h
> @@ -12,9 +12,10 @@
>
> void erofs_inode_manager_init(void);
> unsigned int erofs_iput(struct erofs_inode *inode);
> -erofs_nid_t erofs_lookupnid(struct erofs_inode *inode);
> +erofs_nid_t erofs_lookupnid(struct erofs_sb_info *sbi, struct erofs_inode *inode);
> struct erofs_inode *erofs_mkfs_build_tree_from_path(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_inode *parent,
> const char *path);
>
> diff --git a/include/erofs/internal.h b/include/erofs/internal.h
> index 49a883e..ff79fe9 100644
> --- a/include/erofs/internal.h
> +++ b/include/erofs/internal.h
> @@ -68,12 +68,9 @@ struct erofs_sb_info {
> u32 checksum;
> };
>
> -/* global sbi */
> -extern struct erofs_sb_info sbi;
> -
> -static inline erofs_off_t iloc(erofs_nid_t nid)
> +static inline erofs_off_t iloc(struct erofs_sb_info *sbi, erofs_nid_t nid)
> {
> - return blknr_to_addr(sbi.meta_blkaddr) + (nid << sbi.islotbits);
> + return blknr_to_addr(sbi->meta_blkaddr) + (nid << sbi->islotbits);
> }
>
> #define EROFS_FEATURE_FUNCS(name, compat, feature) \
> @@ -253,20 +250,31 @@ struct erofs_map_blocks {
> int erofs_read_superblock(struct erofs_device devfd, struct erofs_sb_info *sbi);
>
> /* namei.c */
> -int erofs_read_inode_from_disk(struct erofs_device fd, struct erofs_inode *vi);
> -int erofs_ilookup(struct erofs_device devfd, const char *path, struct erofs_inode *vi);
> +int erofs_read_inode_from_disk(
> + struct erofs_device fd,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *vi);
> +int erofs_ilookup(
> + struct erofs_device devfd,
> + struct erofs_sb_info *sbi,
> + const char *path, struct erofs_inode *vi);
>
> /* data.c */
> -int erofs_pread(struct erofs_device fd, struct erofs_inode *inode, char *buf,
> +int erofs_pread(
> + struct erofs_device fd,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode, char *buf,
> erofs_off_t count, erofs_off_t offset);
> int erofs_map_blocks(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_inode *inode,
> struct erofs_map_blocks *map, int flags);
> /* zmap.c */
> -int z_erofs_fill_inode(struct erofs_inode *vi);
> +int z_erofs_fill_inode(struct erofs_inode *vi, struct erofs_sb_info *sbi);
> int z_erofs_map_blocks_iter(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_inode *vi,
> struct erofs_map_blocks *map,
> int flags);
> diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
> index f0c4c26..c8593e1 100644
> --- a/include/erofs/xattr.h
> +++ b/include/erofs/xattr.h
> @@ -42,6 +42,6 @@
>
> int erofs_prepare_xattr_ibody(struct erofs_inode *inode);
> char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size);
> -int erofs_build_shared_xattrs_from_path(const char *path);
> +int erofs_build_shared_xattrs_from_path(const char *path, struct erofs_sb_info *sbi);
>
> #endif
> diff --git a/lib/compress.c b/lib/compress.c
> index 766b75b..1e1ffde 100644
> --- a/lib/compress.c
> +++ b/lib/compress.c
> @@ -59,8 +59,10 @@ static void vle_write_indexes_final(struct z_erofs_vle_compress_ctx *ctx)
> ctx->metacur += sizeof(di);
> }
>
> -static void vle_write_indexes(struct z_erofs_vle_compress_ctx *ctx,
> - unsigned int count, bool raw)
> +static void vle_write_indexes(
> + struct z_erofs_vle_compress_ctx *ctx,
> + struct erofs_sb_info *sbi,
> + unsigned int count, bool raw)
> {
> unsigned int clusterofs = ctx->clusterofs;
> unsigned int d0 = 0, d1 = (clusterofs + count) / EROFS_BLKSIZ;
> @@ -89,7 +91,7 @@ static void vle_write_indexes(struct z_erofs_vle_compress_ctx *ctx,
>
> do {
> /* XXX: big pcluster feature should be per-inode */
> - if (d0 == 1 && erofs_sb_has_big_pcluster(&sbi)) {
> + if (d0 == 1 && erofs_sb_has_big_pcluster(sbi)) {
> type = Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD;
> di.di_u.delta[0] = cpu_to_le16(ctx->compressedblks |
> Z_EROFS_VLE_DI_D0_CBLKCNT);
> @@ -122,6 +124,7 @@ static void vle_write_indexes(struct z_erofs_vle_compress_ctx *ctx,
>
> static int write_uncompressed_extent(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct z_erofs_vle_compress_ctx *ctx,
> unsigned int *len, char *dst)
> {
> @@ -129,7 +132,7 @@ static int write_uncompressed_extent(
> unsigned int count;
>
> /* reset clusterofs to 0 if permitted */
> - if (!erofs_sb_has_lz4_0padding(&sbi) && ctx->clusterofs &&
> + if (!erofs_sb_has_lz4_0padding(sbi) && ctx->clusterofs &&
> ctx->head >= ctx->clusterofs) {
> ctx->head -= ctx->clusterofs;
> *len += ctx->clusterofs;
> @@ -166,6 +169,7 @@ static unsigned int z_erofs_get_max_pclusterblks(struct erofs_inode *inode)
>
> static int vle_compress_one(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_inode *inode,
> struct z_erofs_vle_compress_ctx *ctx,
> bool final)
> @@ -201,7 +205,7 @@ static int vle_compress_one(
> erofs_strerror(ret));
> }
> nocompression:
> - ret = write_uncompressed_extent(erofs_dev, ctx, &len, dst);
> + ret = write_uncompressed_extent(erofs_dev, sbi, ctx, &len, dst);
> if (ret < 0)
> return ret;
> count = ret;
> @@ -210,14 +214,14 @@ nocompression:
> } else {
> const unsigned int tailused = ret & (EROFS_BLKSIZ - 1);
> const unsigned int padding =
> - erofs_sb_has_lz4_0padding(&sbi) && tailused ?
> + erofs_sb_has_lz4_0padding(sbi) && tailused ?
> EROFS_BLKSIZ - tailused : 0;
>
> ctx->compressedblks = DIV_ROUND_UP(ret, EROFS_BLKSIZ);
> DBG_BUGON(ctx->compressedblks * EROFS_BLKSIZ >= count);
>
> /* zero out garbage trailing data for non-0padding */
> - if (!erofs_sb_has_lz4_0padding(&sbi))
> + if (!erofs_sb_has_lz4_0padding(sbi))
> memset(dst + ret, 0,
> roundup(ret, EROFS_BLKSIZ) - ret);
>
> @@ -234,7 +238,7 @@ nocompression:
>
> ctx->head += count;
> /* write compression indexes for this pcluster */
> - vle_write_indexes(ctx, count, raw);
> + vle_write_indexes(ctx, sbi, count, raw);
>
> ctx->blkaddr += ctx->compressedblks;
> len -= count;
> @@ -287,7 +291,9 @@ static void *parse_legacy_indexes(struct z_erofs_compressindex_vec *cv,
> return db + nr;
> }
>
> -static void *write_compacted_indexes(u8 *out,
> +static void *write_compacted_indexes(
> + struct erofs_sb_info *sbi,
> + u8 *out,
> struct z_erofs_compressindex_vec *cv,
> erofs_blk_t *blkaddr_ret,
> unsigned int destsize,
> @@ -306,7 +312,7 @@ static void *write_compacted_indexes(u8 *out,
> return ERR_PTR(-EINVAL);
> encodebits = (vcnt * destsize * 8 - 32) / vcnt;
> blkaddr = *blkaddr_ret;
> - update_blkaddr = erofs_sb_has_big_pcluster(&sbi);
> + update_blkaddr = erofs_sb_has_big_pcluster(sbi);
>
> pos = 0;
> for (i = 0; i < vcnt; ++i) {
> @@ -354,7 +360,9 @@ static void *write_compacted_indexes(u8 *out,
> return out + destsize * vcnt;
> }
>
> -int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
> +int z_erofs_convert_to_compacted_format(
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode,
> erofs_blk_t blkaddr,
> unsigned int legacymetasize,
> void *compressmeta)
> @@ -402,7 +410,7 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
>
> dummy_head = false;
> /* prior to bigpcluster, blkaddr was bumped up once coming into HEAD */
> - if (!erofs_sb_has_big_pcluster(&sbi)) {
> + if (!erofs_sb_has_big_pcluster(sbi)) {
> --blkaddr;
> dummy_head = true;
> }
> @@ -410,7 +418,7 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
> /* generate compacted_4b_initial */
> while (compacted_4b_initial) {
> in = parse_legacy_indexes(cv, 2, in);
> - out = write_compacted_indexes(out, cv, &blkaddr,
> + out = write_compacted_indexes(sbi, out, cv, &blkaddr,
> 4, logical_clusterbits, false,
> &dummy_head);
> compacted_4b_initial -= 2;
> @@ -420,7 +428,7 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
> /* generate compacted_2b */
> while (compacted_2b) {
> in = parse_legacy_indexes(cv, 16, in);
> - out = write_compacted_indexes(out, cv, &blkaddr,
> + out = write_compacted_indexes(sbi, out, cv, &blkaddr,
> 2, logical_clusterbits, false,
> &dummy_head);
> compacted_2b -= 16;
> @@ -430,7 +438,7 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
> /* generate compacted_4b_end */
> while (compacted_4b_end > 1) {
> in = parse_legacy_indexes(cv, 2, in);
> - out = write_compacted_indexes(out, cv, &blkaddr,
> + out = write_compacted_indexes(sbi, out, cv, &blkaddr,
> 4, logical_clusterbits, false,
> &dummy_head);
> compacted_4b_end -= 2;
> @@ -440,7 +448,7 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
> if (compacted_4b_end) {
> memset(cv, 0, sizeof(cv));
> in = parse_legacy_indexes(cv, 1, in);
> - out = write_compacted_indexes(out, cv, &blkaddr,
> + out = write_compacted_indexes(sbi, out, cv, &blkaddr,
> 4, logical_clusterbits, true,
> &dummy_head);
> }
> @@ -464,7 +472,10 @@ static void z_erofs_write_mapheader(struct erofs_inode *inode,
> memcpy(compressmeta, &h, sizeof(struct z_erofs_map_header));
> }
>
> -int erofs_write_compressed_file(struct erofs_device erofs_dev, struct erofs_inode *inode)
> +int erofs_write_compressed_file(
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode)
> {
> struct erofs_buffer_head *bh;
> struct z_erofs_vle_compress_ctx ctx;
> @@ -499,7 +510,7 @@ int erofs_write_compressed_file(struct erofs_device erofs_dev, struct erofs_inod
> inode->datalayout = EROFS_INODE_FLAT_COMPRESSION_LEGACY;
> }
>
> - if (erofs_sb_has_big_pcluster(&sbi)) {
> + if (erofs_sb_has_big_pcluster(sbi)) {
> inode->z_advise |= Z_EROFS_ADVISE_BIG_PCLUSTER_1;
> if (inode->datalayout == EROFS_INODE_FLAT_COMPRESSION)
> inode->z_advise |= Z_EROFS_ADVISE_BIG_PCLUSTER_2;
> @@ -530,13 +541,13 @@ int erofs_write_compressed_file(struct erofs_device erofs_dev, struct erofs_inod
> ctx.tail += readcount;
>
> /* do one compress round */
> - ret = vle_compress_one(erofs_dev, inode, &ctx, false);
> + ret = vle_compress_one(erofs_dev, sbi, inode, &ctx, false);
> if (ret)
> goto err_bdrop;
> }
>
> /* do the final round */
> - ret = vle_compress_one(erofs_dev, inode, &ctx, true);
> + ret = vle_compress_one(erofs_dev, sbi, inode, &ctx, true);
> if (ret)
> goto err_bdrop;
>
> @@ -570,7 +581,7 @@ int erofs_write_compressed_file(struct erofs_device erofs_dev, struct erofs_inod
> if (inode->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) {
> inode->extent_isize = legacymetasize;
> } else {
> - ret = z_erofs_convert_to_compacted_format(inode, blkaddr,
> + ret = z_erofs_convert_to_compacted_format(sbi, inode, blkaddr,
> legacymetasize,
> compressmeta);
> DBG_BUGON(ret);
> @@ -597,12 +608,15 @@ static int erofs_get_compress_algorithm_id(const char *name)
> return -ENOTSUP;
> }
>
> -int z_erofs_build_compr_cfgs(struct erofs_device erofs_dev, struct erofs_buffer_head *sb_bh)
> +int z_erofs_build_compr_cfgs(
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_buffer_head *sb_bh)
> {
> struct erofs_buffer_head *bh = sb_bh;
> int ret = 0;
>
> - if (sbi.available_compr_algs & (1 << Z_EROFS_COMPRESSION_LZ4)) {
> + if (sbi->available_compr_algs & (1 << Z_EROFS_COMPRESSION_LZ4)) {
> struct {
> __le16 size;
> struct z_erofs_lz4_cfgs lz4;
> @@ -610,7 +624,7 @@ int z_erofs_build_compr_cfgs(struct erofs_device erofs_dev, struct erofs_buffer_
> .size = cpu_to_le16(sizeof(struct z_erofs_lz4_cfgs)),
> .lz4 = {
> .max_distance =
> - cpu_to_le16(sbi.lz4_max_distance),
> + cpu_to_le16(sbi->lz4_max_distance),
> .max_pclusterblks = cfg.c_pclusterblks_max,
> }
> };
> @@ -651,10 +665,14 @@ int z_erofs_build_compr_cfgs(struct erofs_device erofs_dev, struct erofs_buffer_
> return ret;
> }
>
> -int z_erofs_compress_init(struct erofs_device erofs_dev, struct erofs_buffer_head *sb_bh)
> +int z_erofs_compress_init(
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_buffer_head *sb_bh)
> {
> /* initialize for primary compression algorithm */
> int ret = erofs_compressor_init(&compresshandle,
> + sbi,
> cfg.c_compr_alg_master);
>
> if (ret)
> @@ -666,7 +684,7 @@ int z_erofs_compress_init(struct erofs_device erofs_dev, struct erofs_buffer_hea
> */
> if (!cfg.c_compr_alg_master ||
> (cfg.c_legacy_compress && !strcmp(cfg.c_compr_alg_master, "lz4")))
> - erofs_sb_clear_lz4_0padding(&sbi);
> + erofs_sb_clear_lz4_0padding(sbi);
>
> if (!cfg.c_compr_alg_master)
> return 0;
> @@ -694,16 +712,16 @@ int z_erofs_compress_init(struct erofs_device erofs_dev, struct erofs_buffer_hea
> cfg.c_pclusterblks_max);
> return -EINVAL;
> }
> - erofs_sb_set_big_pcluster(&sbi);
> + erofs_sb_set_big_pcluster(sbi);
> erofs_warn("EXPERIMENTAL big pcluster feature in use. Use at your own risk!");
> }
>
> if (ret != Z_EROFS_COMPRESSION_LZ4)
> - erofs_sb_set_compr_cfgs(&sbi);
> + erofs_sb_set_compr_cfgs(sbi);
>
> - if (erofs_sb_has_compr_cfgs(&sbi)) {
> - sbi.available_compr_algs |= 1 << ret;
> - return z_erofs_build_compr_cfgs(erofs_dev, sb_bh);
> + if (erofs_sb_has_compr_cfgs(sbi)) {
> + sbi->available_compr_algs |= 1 << ret;
> + return z_erofs_build_compr_cfgs(erofs_dev, sbi, sb_bh);
> }
> return 0;
> }
> diff --git a/lib/compressor.c b/lib/compressor.c
> index 6362825..3b8d193 100644
> --- a/lib/compressor.c
> +++ b/lib/compressor.c
> @@ -62,7 +62,10 @@ int erofs_compressor_setlevel(struct erofs_compress *c, int compression_level)
> return 0;
> }
>
> -int erofs_compressor_init(struct erofs_compress *c, char *alg_name)
> +int erofs_compressor_init(
> + struct erofs_compress *c,
> + struct erofs_sb_info *sbi,
> + char *alg_name)
> {
> int ret, i;
>
> @@ -84,7 +87,7 @@ int erofs_compressor_init(struct erofs_compress *c, char *alg_name)
> if (alg_name && strcmp(alg_name, compressors[i]->name))
> continue;
>
> - ret = compressors[i]->init(c);
> + ret = compressors[i]->init(c, sbi);
> if (!ret) {
> DBG_BUGON(!c->alg);
> return 0;
> diff --git a/lib/compressor.h b/lib/compressor.h
> index 1ea2724..446c013 100644
> --- a/lib/compressor.h
> +++ b/lib/compressor.h
> @@ -10,6 +10,7 @@
> #include "erofs/defs.h"
>
> struct erofs_compress;
> +struct erofs_sb_info;
>
> struct erofs_compressor {
> const char *name;
> @@ -17,7 +18,7 @@ struct erofs_compressor {
> int default_level;
> int best_level;
>
> - int (*init)(struct erofs_compress *c);
> + int (*init)(struct erofs_compress *c, struct erofs_sb_info *sbi);
> int (*exit)(struct erofs_compress *c);
> int (*setlevel)(struct erofs_compress *c, int compression_level);
>
> @@ -50,7 +51,7 @@ int erofs_compress_destsize(struct erofs_compress *c,
> void *dst, unsigned int dstsize);
>
> int erofs_compressor_setlevel(struct erofs_compress *c, int compression_level);
> -int erofs_compressor_init(struct erofs_compress *c, char *alg_name);
> +int erofs_compressor_init(struct erofs_compress *c, struct erofs_sb_info *sbi, char *alg_name);
> int erofs_compressor_exit(struct erofs_compress *c);
>
> #endif
> diff --git a/lib/compressor_lz4.c b/lib/compressor_lz4.c
> index fc8c23c..ffdbb9f 100644
> --- a/lib/compressor_lz4.c
> +++ b/lib/compressor_lz4.c
> @@ -30,10 +30,12 @@ static int compressor_lz4_exit(struct erofs_compress *c)
> return 0;
> }
>
> -static int compressor_lz4_init(struct erofs_compress *c)
> +static int compressor_lz4_init(
> + struct erofs_compress *c,
> + struct erofs_sb_info *sbi)
> {
> c->alg = &erofs_compressor_lz4;
> - sbi.lz4_max_distance = LZ4_DISTANCE_MAX;
> + sbi->lz4_max_distance = LZ4_DISTANCE_MAX;
> return 0;
> }
>
> diff --git a/lib/compressor_lz4hc.c b/lib/compressor_lz4hc.c
> index 3f68b00..f573cd2 100644
> --- a/lib/compressor_lz4hc.c
> +++ b/lib/compressor_lz4hc.c
> @@ -36,7 +36,7 @@ static int compressor_lz4hc_exit(struct erofs_compress *c)
> return 0;
> }
>
> -static int compressor_lz4hc_init(struct erofs_compress *c)
> +static int compressor_lz4hc_init(struct erofs_compress *c, struct erofs_sb_info *sbi)
> {
> c->alg = &erofs_compressor_lz4hc;
>
> @@ -44,7 +44,7 @@ static int compressor_lz4hc_init(struct erofs_compress *c)
> if (!c->private_data)
> return -ENOMEM;
>
> - sbi.lz4_max_distance = LZ4_DISTANCE_MAX;
> + sbi->lz4_max_distance = LZ4_DISTANCE_MAX;
> return 0;
> }
>
> diff --git a/lib/config.c b/lib/config.c
> index 7488e08..7313588 100644
> --- a/lib/config.c
> +++ b/lib/config.c
> @@ -10,7 +10,6 @@
> #include "erofs/internal.h"
>
> struct erofs_configure cfg;
> -struct erofs_sb_info sbi;
>
> void erofs_init_config(struct erofs_configure *cfg)
> {
> diff --git a/lib/data.c b/lib/data.c
> index d9d20ec..e6fe1d6 100644
> --- a/lib/data.c
> +++ b/lib/data.c
> @@ -10,9 +10,11 @@
> #include "erofs/trace.h"
> #include "erofs/decompress.h"
>
> -static int erofs_map_blocks_flatmode(struct erofs_inode *inode,
> - struct erofs_map_blocks *map,
> - int flags)
> +static int erofs_map_blocks_flatmode(
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode,
> + struct erofs_map_blocks *map,
> + int flags)
> {
> int err = 0;
> erofs_blk_t nblocks, lastblk;
> @@ -33,7 +35,7 @@ static int erofs_map_blocks_flatmode(struct erofs_inode *inode,
> map->m_plen = blknr_to_addr(lastblk) - offset;
> } else if (tailendpacking) {
> /* 2 - inode inline B: inode, [xattrs], inline last blk... */
> - map->m_pa = iloc(vi->nid) + vi->inode_isize +
> + map->m_pa = iloc(sbi, vi->nid) + vi->inode_isize +
> vi->xattr_isize + erofs_blkoff(map->m_la);
> map->m_plen = inode->i_size - offset;
>
> @@ -63,6 +65,7 @@ err_out:
>
> int erofs_map_blocks(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_inode *inode,
> struct erofs_map_blocks *map, int flags)
> {
> @@ -82,7 +85,7 @@ int erofs_map_blocks(
> }
>
> if (vi->datalayout != EROFS_INODE_CHUNK_BASED)
> - return erofs_map_blocks_flatmode(inode, map, flags);
> + return erofs_map_blocks_flatmode(sbi, inode, map, flags);
>
> if (vi->u.chunkformat & EROFS_CHUNK_FORMAT_INDEXES)
> unit = sizeof(*idx); /* chunk index */
> @@ -90,7 +93,7 @@ int erofs_map_blocks(
> unit = EROFS_BLOCK_MAP_ENTRY_SIZE; /* block map */
>
> chunknr = map->m_la >> vi->u.chunkbits;
> - pos = roundup(iloc(vi->nid) + vi->inode_isize +
> + pos = roundup(iloc(sbi, vi->nid) + vi->inode_isize +
> vi->xattr_isize, unit) + unit * chunknr;
>
> err = blk_read(erofs_dev, buf, erofs_blknr(pos), 1);
> @@ -137,7 +140,10 @@ out:
> return err;
> }
>
> -static int erofs_read_raw_data(struct erofs_device erofs_dev, struct erofs_inode *inode, char *buffer,
> +static int erofs_read_raw_data(
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode, char *buffer,
> erofs_off_t size, erofs_off_t offset)
> {
> struct erofs_map_blocks map = {
> @@ -151,7 +157,7 @@ static int erofs_read_raw_data(struct erofs_device erofs_dev, struct erofs_inode
> erofs_off_t eend;
>
> map.m_la = ptr;
> - ret = erofs_map_blocks(erofs_dev, inode, &map, 0);
> + ret = erofs_map_blocks(erofs_dev, sbi, inode, &map, 0);
> if (ret)
> return ret;
>
> @@ -188,6 +194,7 @@ static int erofs_read_raw_data(struct erofs_device erofs_dev, struct erofs_inode
>
> static int z_erofs_read_data(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_inode *inode,
> char *buffer,
> erofs_off_t size,
> @@ -207,7 +214,7 @@ static int z_erofs_read_data(
> while (end > offset) {
> map.m_la = end - 1;
>
> - ret = z_erofs_map_blocks_iter(erofs_dev, inode, &map, 0);
> + ret = z_erofs_map_blocks_iter(erofs_dev, sbi, inode, &map, 0);
> if (ret)
> break;
>
> @@ -263,7 +270,7 @@ static int z_erofs_read_data(
> .decodedlength = length,
> .alg = algorithmformat,
> .partial_decoding = partial
> - });
> + }, sbi);
> if (ret < 0)
> break;
> }
> @@ -272,17 +279,20 @@ static int z_erofs_read_data(
> return ret < 0 ? ret : 0;
> }
>
> -int erofs_pread(struct erofs_device fd, struct erofs_inode *inode, char *buf,
> +int erofs_pread(
> + struct erofs_device fd,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode, char *buf,
> erofs_off_t count, erofs_off_t offset)
> {
> switch (inode->datalayout) {
> case EROFS_INODE_FLAT_PLAIN:
> case EROFS_INODE_FLAT_INLINE:
> case EROFS_INODE_CHUNK_BASED:
> - return erofs_read_raw_data(fd, inode, buf, count, offset);
> + return erofs_read_raw_data(fd, sbi, inode, buf, count, offset);
> case EROFS_INODE_FLAT_COMPRESSION_LEGACY:
> case EROFS_INODE_FLAT_COMPRESSION:
> - return z_erofs_read_data(fd, inode, buf, count, offset);
> + return z_erofs_read_data(fd, sbi, inode, buf, count, offset);
> default:
> break;
> }
> diff --git a/lib/decompress.c b/lib/decompress.c
> index 6a60400..483bd52 100644
> --- a/lib/decompress.c
> +++ b/lib/decompress.c
> @@ -12,7 +12,7 @@
> #ifdef HAVE_LIBLZMA
> #include <lzma.h>
>
> -static int z_erofs_decompress_lzma(struct z_erofs_decompress_req *rq)
> +static int z_erofs_decompress_lzma(struct z_erofs_decompress_req *rq, struct erofs_sb_info *sbi)
> {
> int ret = 0;
> u8 *dest = (u8 *)rq->out;
> @@ -73,7 +73,7 @@ out:
> #ifdef LZ4_ENABLED
> #include <lz4.h>
>
> -static int z_erofs_decompress_lz4(struct z_erofs_decompress_req *rq)
> +static int z_erofs_decompress_lz4(struct z_erofs_decompress_req *rq, struct erofs_sb_info *sbi)
> {
> int ret = 0;
> char *dest = rq->out;
> @@ -82,7 +82,7 @@ static int z_erofs_decompress_lz4(struct z_erofs_decompress_req *rq)
> bool support_0padding = false;
> unsigned int inputmargin = 0;
>
> - if (erofs_sb_has_lz4_0padding(&sbi)) {
> + if (erofs_sb_has_lz4_0padding(sbi)) {
> support_0padding = true;
>
> while (!src[inputmargin & ~PAGE_MASK])
> @@ -126,7 +126,7 @@ out:
> }
> #endif
>
> -int z_erofs_decompress(struct z_erofs_decompress_req *rq)
> +int z_erofs_decompress(struct z_erofs_decompress_req *rq, struct erofs_sb_info *sbi)
> {
> if (rq->alg == Z_EROFS_COMPRESSION_SHIFTED) {
> if (rq->inputsize != EROFS_BLKSIZ)
> @@ -142,11 +142,11 @@ int z_erofs_decompress(struct z_erofs_decompress_req *rq)
>
> #ifdef LZ4_ENABLED
> if (rq->alg == Z_EROFS_COMPRESSION_LZ4)
> - return z_erofs_decompress_lz4(rq);
> + return z_erofs_decompress_lz4(rq, sbi);
> #endif
> #ifdef HAVE_LIBLZMA
> if (rq->alg == Z_EROFS_COMPRESSION_LZMA)
> - return z_erofs_decompress_lzma(rq);
> + return z_erofs_decompress_lzma(rq, sbi);
> #endif
> return -EOPNOTSUPP;
> }
> diff --git a/lib/inode.c b/lib/inode.c
> index d1adb49..70525fa 100644
> --- a/lib/inode.c
> +++ b/lib/inode.c
> @@ -387,7 +387,10 @@ static int write_uncompressed_file_from_fd(
> return 0;
> }
>
> -int erofs_write_file(struct erofs_device erofs_dev, struct erofs_inode *inode)
> +int erofs_write_file(
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *inode)
> {
> int ret, fd;
>
> @@ -403,7 +406,7 @@ int erofs_write_file(struct erofs_device erofs_dev, struct erofs_inode *inode)
> }
>
> if (cfg.c_compr_alg_master && erofs_file_is_compressible(inode)) {
> - ret = erofs_write_compressed_file(erofs_dev, inode);
> + ret = erofs_write_compressed_file(erofs_dev, sbi, inode);
>
> if (!ret || ret != -ENOSPC)
> return ret;
> @@ -799,7 +802,9 @@ static int erofs_droid_inode_fsconfig(struct erofs_inode *inode,
> }
> #endif
>
> -static int erofs_fill_inode(struct erofs_inode *inode,
> +static int erofs_fill_inode(
> + struct erofs_inode *inode,
> + struct erofs_sb_info *sbi,
> struct stat64 *st,
> const char *path)
> {
> @@ -815,11 +820,11 @@ static int erofs_fill_inode(struct erofs_inode *inode,
>
> switch (cfg.c_timeinherit) {
> case TIMESTAMP_CLAMPING:
> - if (st->st_ctime < sbi.build_time)
> + if (st->st_ctime < sbi->build_time)
> break;
> case TIMESTAMP_FIXED:
> - inode->i_ctime = sbi.build_time;
> - inode->i_ctime_nsec = sbi.build_time_nsec;
> + inode->i_ctime = sbi->build_time;
> + inode->i_ctime_nsec = sbi->build_time_nsec;
> default:
> break;
> }
> @@ -865,7 +870,7 @@ static int erofs_fill_inode(struct erofs_inode *inode,
> return 0;
> }
>
> -static struct erofs_inode *erofs_new_inode(void)
> +static struct erofs_inode *erofs_new_inode(struct erofs_sb_info *sbi)
> {
> struct erofs_inode *inode;
>
> @@ -873,7 +878,7 @@ static struct erofs_inode *erofs_new_inode(void)
> if (!inode)
> return ERR_PTR(-ENOMEM);
>
> - inode->i_ino[0] = sbi.inos++; /* inode serial number */
> + inode->i_ino[0] = sbi->inos++; /* inode serial number */
> inode->i_count = 1;
>
> init_list_head(&inode->i_subdirs);
> @@ -882,7 +887,8 @@ static struct erofs_inode *erofs_new_inode(void)
> }
>
> /* get the inode from the (source) path */
> -static struct erofs_inode *erofs_iget_from_path(const char *path, bool is_src)
> +static struct erofs_inode *erofs_iget_from_path(
> + struct erofs_sb_info *sbi, const char *path, bool is_src)
> {
> struct stat64 st;
> struct erofs_inode *inode;
> @@ -908,11 +914,11 @@ static struct erofs_inode *erofs_iget_from_path(const char *path, bool is_src)
> }
>
> /* cannot find in the inode cache */
> - inode = erofs_new_inode();
> + inode = erofs_new_inode(sbi);
> if (IS_ERR(inode))
> return inode;
>
> - ret = erofs_fill_inode(inode, &st, path);
> + ret = erofs_fill_inode(inode, sbi, &st, path);
> if (ret) {
> free(inode);
> return ERR_PTR(ret);
> @@ -921,7 +927,7 @@ static struct erofs_inode *erofs_iget_from_path(const char *path, bool is_src)
> return inode;
> }
>
> -static void erofs_fixup_meta_blkaddr(struct erofs_inode *rootdir)
> +static void erofs_fixup_meta_blkaddr(struct erofs_sb_info *sbi, struct erofs_inode *rootdir)
> {
> const erofs_off_t rootnid_maxoffset = 0xffff << EROFS_ISLOTBITS;
> struct erofs_buffer_head *const bh = rootdir->bh;
> @@ -934,11 +940,11 @@ static void erofs_fixup_meta_blkaddr(struct erofs_inode *rootdir)
> meta_offset = round_up(off - rootnid_maxoffset, EROFS_BLKSIZ);
> else
> meta_offset = 0;
> - sbi.meta_blkaddr = erofs_blknr(meta_offset);
> + sbi->meta_blkaddr = erofs_blknr(meta_offset);
> rootdir->nid = (off - meta_offset) >> EROFS_ISLOTBITS;
> }
>
> -erofs_nid_t erofs_lookupnid(struct erofs_inode *inode)
> +erofs_nid_t erofs_lookupnid(struct erofs_sb_info *sbi, struct erofs_inode *inode)
> {
> struct erofs_buffer_head *const bh = inode->bh;
> erofs_off_t off, meta_offset;
> @@ -949,21 +955,24 @@ erofs_nid_t erofs_lookupnid(struct erofs_inode *inode)
> erofs_mapbh(bh->block);
> off = erofs_btell(bh, false);
>
> - meta_offset = blknr_to_addr(sbi.meta_blkaddr);
> + meta_offset = blknr_to_addr(sbi->meta_blkaddr);
> DBG_BUGON(off < meta_offset);
> return inode->nid = (off - meta_offset) >> EROFS_ISLOTBITS;
> }
>
> -static void erofs_d_invalidate(struct erofs_dentry *d)
> +static void erofs_d_invalidate(
> + struct erofs_sb_info *sbi, struct erofs_dentry *d)
> {
> struct erofs_inode *const inode = d->inode;
>
> - d->nid = erofs_lookupnid(inode);
> + d->nid = erofs_lookupnid(sbi, inode);
> erofs_iput(inode);
> }
>
> static struct erofs_inode *erofs_mkfs_build_tree(
> - struct erofs_device erofs_dev, struct erofs_inode *dir)
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *dir)
> {
> int ret;
> DIR *_dir;
> @@ -992,7 +1001,7 @@ static struct erofs_inode *erofs_mkfs_build_tree(
> if (ret)
> return ERR_PTR(ret);
> } else {
> - ret = erofs_write_file(erofs_dev, dir);
> + ret = erofs_write_file(erofs_dev, sbi, dir);
> if (ret)
> return ERR_PTR(ret);
> }
> @@ -1055,14 +1064,14 @@ static struct erofs_inode *erofs_mkfs_build_tree(
> goto err;
>
> if (IS_ROOT(dir))
> - erofs_fixup_meta_blkaddr(dir);
> + erofs_fixup_meta_blkaddr(sbi, dir);
>
> list_for_each_entry(d, &dir->i_subdirs, d_child) {
> char buf[PATH_MAX];
> unsigned char ftype;
>
> if (is_dot_dotdot(d->name)) {
> - erofs_d_invalidate(d);
> + erofs_d_invalidate(sbi, d);
> continue;
> }
>
> @@ -1073,7 +1082,7 @@ static struct erofs_inode *erofs_mkfs_build_tree(
> goto fail;
> }
>
> - d->inode = erofs_mkfs_build_tree_from_path(erofs_dev, dir, buf);
> + d->inode = erofs_mkfs_build_tree_from_path(erofs_dev, sbi, dir, buf);
> if (IS_ERR(d->inode)) {
> ret = PTR_ERR(d->inode);
> fail:
> @@ -1086,7 +1095,7 @@ fail:
> DBG_BUGON(ftype == EROFS_FT_DIR && d->type != ftype);
> d->type = ftype;
>
> - erofs_d_invalidate(d);
> + erofs_d_invalidate(sbi, d);
> erofs_info("add file %s/%s (nid %llu, type %d)",
> dir->i_srcpath, d->name, (unsigned long long)d->nid,
> d->type);
> @@ -1103,10 +1112,11 @@ err:
>
> struct erofs_inode *erofs_mkfs_build_tree_from_path(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_inode *parent,
> const char *path)
> {
> - struct erofs_inode *const inode = erofs_iget_from_path(path, true);
> + struct erofs_inode *const inode = erofs_iget_from_path(sbi, path, true);
>
> if (IS_ERR(inode))
> return inode;
> @@ -1123,5 +1133,5 @@ struct erofs_inode *erofs_mkfs_build_tree_from_path(
> else
> inode->i_parent = inode; /* rootdir mark */
>
> - return erofs_mkfs_build_tree(erofs_dev, inode);
> + return erofs_mkfs_build_tree(erofs_dev, sbi, inode);
> }
> diff --git a/lib/namei.c b/lib/namei.c
> index 57041f5..ac65425 100644
> --- a/lib/namei.c
> +++ b/lib/namei.c
> @@ -22,13 +22,16 @@ static dev_t erofs_new_decode_dev(u32 dev)
> return makedev(major, minor);
> }
>
> -int erofs_read_inode_from_disk(struct erofs_device fd, struct erofs_inode *vi)
> +int erofs_read_inode_from_disk(
> + struct erofs_device fd,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *vi)
> {
> int ret, ifmt;
> char buf[sizeof(struct erofs_inode_extended)];
> struct erofs_inode_compact *dic;
> struct erofs_inode_extended *die;
> - const erofs_off_t inode_loc = iloc(vi->nid);
> + const erofs_off_t inode_loc = iloc(sbi, vi->nid);
>
> ret = dev_read(fd, buf, inode_loc, sizeof(*dic));
> if (ret < 0)
> @@ -114,8 +117,8 @@ int erofs_read_inode_from_disk(struct erofs_device fd, struct erofs_inode *vi)
> vi->i_gid = le16_to_cpu(dic->i_gid);
> vi->i_nlink = le16_to_cpu(dic->i_nlink);
>
> - vi->i_ctime = sbi.build_time;
> - vi->i_ctime_nsec = sbi.build_time_nsec;
> + vi->i_ctime = sbi->build_time;
> + vi->i_ctime_nsec = sbi->build_time_nsec;
>
> vi->i_size = le32_to_cpu(dic->i_size);
> if (vi->datalayout == EROFS_INODE_CHUNK_BASED)
> @@ -137,7 +140,7 @@ int erofs_read_inode_from_disk(struct erofs_device fd, struct erofs_inode *vi)
> vi->u.chunkbits = LOG_BLOCK_SIZE +
> (vi->u.chunkformat & EROFS_CHUNK_FORMAT_BLKBITS_MASK);
> } else if (erofs_inode_is_data_compressed(vi->datalayout))
> - z_erofs_fill_inode(vi);
> + z_erofs_fill_inode(vi, sbi);
> return 0;
> bogusimode:
> erofs_err("bogus i_mode (%o) @ nid %llu", vi->i_mode, vi->nid | 0ULL);
> @@ -187,7 +190,10 @@ struct nameidata {
> unsigned int ftype;
> };
>
> -int erofs_namei(struct erofs_device fd, struct nameidata *nd,
> +int erofs_namei(
> + struct erofs_device fd,
> + struct erofs_sb_info *sbi,
> + struct nameidata *nd,
> const char *name, unsigned int len)
> {
> erofs_nid_t nid = nd->nid;
> @@ -196,7 +202,7 @@ int erofs_namei(struct erofs_device fd, struct nameidata *nd,
> struct erofs_inode vi = { .nid = nid };
> erofs_off_t offset;
>
> - ret = erofs_read_inode_from_disk(fd, &vi);
> + ret = erofs_read_inode_from_disk(fd, sbi, &vi);
> if (ret)
> return ret;
>
> @@ -207,7 +213,7 @@ int erofs_namei(struct erofs_device fd, struct nameidata *nd,
> struct erofs_dirent *de = (void *)buf;
> unsigned int nameoff;
>
> - ret = erofs_pread(fd, &vi, buf, maxsize, offset);
> + ret = erofs_pread(fd, sbi, &vi, buf, maxsize, offset);
> if (ret)
> return ret;
>
> @@ -233,9 +239,12 @@ int erofs_namei(struct erofs_device fd, struct nameidata *nd,
> return -ENOENT;
> }
>
> -static int link_path_walk(struct erofs_device devfd, const char *name, struct nameidata *nd)
> +static int link_path_walk(
> + struct erofs_device devfd,
> + struct erofs_sb_info *sbi,
> + const char *name, struct nameidata *nd)
> {
> - nd->nid = sbi.root_nid;
> + nd->nid = sbi->root_nid;
>
> while (*name == '/')
> name++;
> @@ -250,7 +259,7 @@ static int link_path_walk(struct erofs_device devfd, const char *name, struct na
> } while (*p != '\0' && *p != '/');
>
> DBG_BUGON(p <= name);
> - ret = erofs_namei(devfd, nd, name, p - name);
> + ret = erofs_namei(devfd, sbi, nd, name, p - name);
> if (ret)
> return ret;
>
> @@ -262,15 +271,18 @@ static int link_path_walk(struct erofs_device devfd, const char *name, struct na
> return 0;
> }
>
> -int erofs_ilookup(struct erofs_device devfd, const char *path, struct erofs_inode *vi)
> +int erofs_ilookup(
> + struct erofs_device devfd,
> + struct erofs_sb_info *sbi,
> + const char *path, struct erofs_inode *vi)
> {
> int ret;
> struct nameidata nd;
>
> - ret = link_path_walk(devfd, path, &nd);
> + ret = link_path_walk(devfd, sbi, path, &nd);
> if (ret)
> return ret;
>
> vi->nid = nd.nid;
> - return erofs_read_inode_from_disk(devfd, vi);
> + return erofs_read_inode_from_disk(devfd, sbi, vi);
> }
> diff --git a/lib/xattr.c b/lib/xattr.c
> index 9f16664..7a1ed9e 100644
> --- a/lib/xattr.c
> +++ b/lib/xattr.c
> @@ -564,7 +564,7 @@ static struct erofs_bhops erofs_write_shared_xattrs_bhops = {
> .flush = erofs_bh_flush_write_shared_xattrs,
> };
>
> -int erofs_build_shared_xattrs_from_path(const char *path)
> +int erofs_build_shared_xattrs_from_path(const char *path, struct erofs_sb_info *sbi)
> {
> int ret;
> struct erofs_buffer_head *bh;
> @@ -604,7 +604,7 @@ int erofs_build_shared_xattrs_from_path(const char *path)
> erofs_mapbh(bh->block);
> off = erofs_btell(bh, false);
>
> - sbi.xattr_blkaddr = off / EROFS_BLKSIZ;
> + sbi->xattr_blkaddr = off / EROFS_BLKSIZ;
> off %= EROFS_BLKSIZ;
> p = 0;
>
> diff --git a/lib/zmap.c b/lib/zmap.c
> index 69fef80..e6e9858 100644
> --- a/lib/zmap.c
> +++ b/lib/zmap.c
> @@ -10,9 +10,9 @@
> #include "erofs/io.h"
> #include "erofs/print.h"
>
> -int z_erofs_fill_inode(struct erofs_inode *vi)
> +int z_erofs_fill_inode(struct erofs_inode *vi, struct erofs_sb_info *sbi)
> {
> - if (!erofs_sb_has_big_pcluster(&sbi) &&
> + if (!erofs_sb_has_big_pcluster(sbi) &&
> vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) {
> vi->z_advise = 0;
> vi->z_algorithmtype[0] = 0;
> @@ -24,7 +24,10 @@ int z_erofs_fill_inode(struct erofs_inode *vi)
> return 0;
> }
>
> -static int z_erofs_fill_inode_lazy(struct erofs_device erofs_dev, struct erofs_inode *vi)
> +static int z_erofs_fill_inode_lazy(
> + struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> + struct erofs_inode *vi)
> {
> int ret;
> erofs_off_t pos;
> @@ -34,9 +37,9 @@ static int z_erofs_fill_inode_lazy(struct erofs_device erofs_dev, struct erofs_i
> if (vi->flags & EROFS_I_Z_INITED)
> return 0;
>
> - DBG_BUGON(!erofs_sb_has_big_pcluster(&sbi) &&
> + DBG_BUGON(!erofs_sb_has_big_pcluster(sbi) &&
> vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY);
> - pos = round_up(iloc(vi->nid) + vi->inode_isize + vi->xattr_isize, 8);
> + pos = round_up(iloc(sbi, vi->nid) + vi->inode_isize + vi->xattr_isize, 8);
>
> ret = dev_read(erofs_dev, buf, pos, sizeof(buf));
> if (ret < 0)
> @@ -101,11 +104,12 @@ static int z_erofs_reload_indexes(
>
> static int legacy_load_cluster_from_disk(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct z_erofs_maprecorder *m,
> unsigned long lcn)
> {
> struct erofs_inode *const vi = m->inode;
> - const erofs_off_t ibase = iloc(vi->nid);
> + const erofs_off_t ibase = iloc(sbi, vi->nid);
> const erofs_off_t pos =
> Z_EROFS_VLE_LEGACY_INDEX_ALIGN(ibase + vi->inode_isize +
> vi->xattr_isize) +
> @@ -295,12 +299,13 @@ static int unpack_compacted_index(struct z_erofs_maprecorder *m,
>
> static int compacted_load_cluster_from_disk(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct z_erofs_maprecorder *m,
> unsigned long lcn, bool lookahead)
> {
> struct erofs_inode *const vi = m->inode;
> const unsigned int lclusterbits = vi->z_logical_clusterbits;
> - const erofs_off_t ebase = round_up(iloc(vi->nid) + vi->inode_isize +
> + const erofs_off_t ebase = round_up(iloc(sbi, vi->nid) + vi->inode_isize +
> vi->xattr_isize, 8) +
> sizeof(struct z_erofs_map_header);
> const unsigned int totalidx = DIV_ROUND_UP(vi->i_size, EROFS_BLKSIZ);
> @@ -352,22 +357,24 @@ out:
>
> static int z_erofs_load_cluster_from_disk(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct z_erofs_maprecorder *m,
> unsigned int lcn, bool lookahead)
> {
> const unsigned int datamode = m->inode->datalayout;
>
> if (datamode == EROFS_INODE_FLAT_COMPRESSION_LEGACY)
> - return legacy_load_cluster_from_disk(erofs_dev, m, lcn);
> + return legacy_load_cluster_from_disk(erofs_dev, sbi, m, lcn);
>
> if (datamode == EROFS_INODE_FLAT_COMPRESSION)
> - return compacted_load_cluster_from_disk(erofs_dev, m, lcn, lookahead);
> + return compacted_load_cluster_from_disk(erofs_dev, sbi, m, lcn, lookahead);
>
> return -EINVAL;
> }
>
> static int z_erofs_extent_lookback(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct z_erofs_maprecorder *m,
> unsigned int lookback_distance)
> {
> @@ -386,7 +393,7 @@ static int z_erofs_extent_lookback(
>
> /* load extent head logical cluster if needed */
> lcn -= lookback_distance;
> - err = z_erofs_load_cluster_from_disk(erofs_dev, m, lcn, false);
> + err = z_erofs_load_cluster_from_disk(erofs_dev, sbi, m, lcn, false);
> if (err)
> return err;
>
> @@ -398,7 +405,7 @@ static int z_erofs_extent_lookback(
> DBG_BUGON(1);
> return -EFSCORRUPTED;
> }
> - return z_erofs_extent_lookback(erofs_dev, m, m->delta[0]);
> + return z_erofs_extent_lookback(erofs_dev, sbi, m, m->delta[0]);
> case Z_EROFS_VLE_CLUSTER_TYPE_PLAIN:
> map->m_flags &= ~EROFS_MAP_ZIPPED;
> /* fallthrough */
> @@ -416,6 +423,7 @@ static int z_erofs_extent_lookback(
>
> static int z_erofs_get_extent_compressedlen(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct z_erofs_maprecorder *m,
> unsigned int initial_lcn)
> {
> @@ -437,7 +445,7 @@ static int z_erofs_get_extent_compressedlen(
> if (m->compressedlcs)
> goto out;
>
> - err = z_erofs_load_cluster_from_disk(erofs_dev, m, lcn, false);
> + err = z_erofs_load_cluster_from_disk(erofs_dev, sbi, m, lcn, false);
> if (err)
> return err;
>
> @@ -485,6 +493,7 @@ err_bonus_cblkcnt:
>
> static int z_erofs_get_extent_decompressedlen(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct z_erofs_maprecorder *m)
> {
> struct erofs_inode *const vi = m->inode;
> @@ -500,7 +509,7 @@ static int z_erofs_get_extent_decompressedlen(
> return 0;
> }
>
> - err = z_erofs_load_cluster_from_disk(erofs_dev, m, lcn, true);
> + err = z_erofs_load_cluster_from_disk(erofs_dev, sbi, m, lcn, true);
> if (err)
> return err;
>
> @@ -529,6 +538,7 @@ static int z_erofs_get_extent_decompressedlen(
>
> int z_erofs_map_blocks_iter(
> struct erofs_device erofs_dev,
> + struct erofs_sb_info *sbi,
> struct erofs_inode *vi,
> struct erofs_map_blocks *map,
> int flags)
> @@ -551,7 +561,7 @@ int z_erofs_map_blocks_iter(
> goto out;
> }
>
> - err = z_erofs_fill_inode_lazy(erofs_dev, vi);
> + err = z_erofs_fill_inode_lazy(erofs_dev, sbi, vi);
> if (err)
> goto out;
>
> @@ -560,7 +570,7 @@ int z_erofs_map_blocks_iter(
> initial_lcn = ofs >> lclusterbits;
> endoff = ofs & ((1 << lclusterbits) - 1);
>
> - err = z_erofs_load_cluster_from_disk(erofs_dev, &m, initial_lcn, false);
> + err = z_erofs_load_cluster_from_disk(erofs_dev, sbi, &m, initial_lcn, false);
> if (err)
> goto out;
>
> @@ -589,7 +599,7 @@ int z_erofs_map_blocks_iter(
> /* fallthrough */
> case Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD:
> /* get the correspoinding first chunk */
> - err = z_erofs_extent_lookback(erofs_dev, &m, m.delta[0]);
> + err = z_erofs_extent_lookback(erofs_dev, sbi, &m, m.delta[0]);
> if (err)
> goto out;
> break;
> @@ -604,12 +614,12 @@ int z_erofs_map_blocks_iter(
> map->m_pa = blknr_to_addr(m.pblk);
> map->m_flags |= EROFS_MAP_MAPPED;
>
> - err = z_erofs_get_extent_compressedlen(erofs_dev, &m, initial_lcn);
> + err = z_erofs_get_extent_compressedlen(erofs_dev, sbi, &m, initial_lcn);
> if (err)
> goto out;
>
> if (flags & EROFS_GET_BLOCKS_FIEMAP) {
> - err = z_erofs_get_extent_decompressedlen(erofs_dev, &m);
> + err = z_erofs_get_extent_decompressedlen(erofs_dev, sbi, &m);
> if (!err)
> map->m_flags |= EROFS_MAP_FULL_MAPPED;
> }
> diff --git a/mkfs/main.c b/mkfs/main.c
> index 16f8060..f7b432e 100644
> --- a/mkfs/main.c
> +++ b/mkfs/main.c
> @@ -109,7 +109,7 @@ static void usage(void)
> print_available_compressors(stderr, ", ");
> }
>
> -static int parse_extended_opts(const char *opts)
> +static int parse_extended_opts(struct erofs_sb_info *sbi, const char *opts)
> {
> #define MATCH_EXTENTED_OPT(opt, token, keylen) \
> (keylen == sizeof(opt) - 1 && !memcmp(token, opt, sizeof(opt) - 1))
> @@ -164,7 +164,7 @@ static int parse_extended_opts(const char *opts)
> if (MATCH_EXTENTED_OPT("nosbcrc", token, keylen)) {
> if (vallen)
> return -EINVAL;
> - erofs_sb_clear_sb_chksum(&sbi);
> + erofs_sb_clear_sb_chksum(sbi);
> }
>
> if (MATCH_EXTENTED_OPT("noinline_data", token, keylen)) {
> @@ -176,7 +176,7 @@ static int parse_extended_opts(const char *opts)
> return 0;
> }
>
> -static int mkfs_parse_options_cfg(int argc, char *argv[])
> +static int mkfs_parse_options_cfg(struct erofs_sb_info *sbi, int argc, char *argv[])
> {
> char *endptr;
> int opt, i;
> @@ -221,7 +221,7 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
> break;
>
> case 'E':
> - opt = parse_extended_opts(optarg);
> + opt = parse_extended_opts(sbi, optarg);
> if (opt)
> return opt;
> break;
> @@ -235,7 +235,7 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
> break;
> #ifdef HAVE_LIBUUID
> case 'U':
> - if (uuid_parse(optarg, sbi.uuid)) {
> + if (uuid_parse(optarg, sbi->uuid)) {
> erofs_err("invalid UUID %s", optarg);
> return -EINVAL;
> }
> @@ -343,7 +343,7 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
> optarg);
> return -EINVAL;
> }
> - erofs_sb_set_chunked_file(&sbi);
> + erofs_sb_set_chunked_file(sbi);
> break;
> case 12:
> quiet = true;
> @@ -385,21 +385,23 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
> return 0;
> }
>
> -int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
> +int erofs_mkfs_update_super_block(
> + struct erofs_sb_info *sbi,
> + struct erofs_buffer_head *bh,
> erofs_nid_t root_nid,
> erofs_blk_t *blocks)
> {
> struct erofs_super_block sb = {
> .magic = cpu_to_le32(EROFS_SUPER_MAGIC_V1),
> .blkszbits = LOG_BLOCK_SIZE,
> - .inos = cpu_to_le64(sbi.inos),
> - .build_time = cpu_to_le64(sbi.build_time),
> - .build_time_nsec = cpu_to_le32(sbi.build_time_nsec),
> + .inos = cpu_to_le64(sbi->inos),
> + .build_time = cpu_to_le64(sbi->build_time),
> + .build_time_nsec = cpu_to_le32(sbi->build_time_nsec),
> .blocks = 0,
> - .meta_blkaddr = sbi.meta_blkaddr,
> - .xattr_blkaddr = sbi.xattr_blkaddr,
> - .feature_incompat = cpu_to_le32(sbi.feature_incompat),
> - .feature_compat = cpu_to_le32(sbi.feature_compat &
> + .meta_blkaddr = sbi->meta_blkaddr,
> + .xattr_blkaddr = sbi->xattr_blkaddr,
> + .feature_incompat = cpu_to_le32(sbi->feature_incompat),
> + .feature_compat = cpu_to_le32(sbi->feature_compat &
> ~EROFS_FEATURE_COMPAT_SB_CHKSUM),
> };
> const unsigned int sb_blksize =
> @@ -409,12 +411,12 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
> *blocks = erofs_mapbh(NULL);
> sb.blocks = cpu_to_le32(*blocks);
> sb.root_nid = cpu_to_le16(root_nid);
> - memcpy(sb.uuid, sbi.uuid, sizeof(sb.uuid));
> + memcpy(sb.uuid, sbi->uuid, sizeof(sb.uuid));
>
> - if (erofs_sb_has_compr_cfgs(&sbi))
> - sb.u1.available_compr_algs = sbi.available_compr_algs;
> + if (erofs_sb_has_compr_cfgs(sbi))
> + sb.u1.available_compr_algs = sbi->available_compr_algs;
> else
> - sb.u1.lz4_max_distance = cpu_to_le16(sbi.lz4_max_distance);
> + sb.u1.lz4_max_distance = cpu_to_le16(sbi->lz4_max_distance);
>
> buf = calloc(sb_blksize, 1);
> if (!buf) {
> @@ -473,17 +475,17 @@ static int erofs_mkfs_superblock_csum_set(struct erofs_device erofs_dev)
> return 0;
> }
>
> -static void erofs_mkfs_default_options(void)
> +static void erofs_mkfs_default_options(struct erofs_sb_info *sbi)
> {
> cfg.c_legacy_compress = false;
> - sbi.feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;
> - sbi.feature_compat = EROFS_FEATURE_COMPAT_SB_CHKSUM;
> + sbi->feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;
> + sbi->feature_compat = EROFS_FEATURE_COMPAT_SB_CHKSUM;
>
> /* generate a default uuid first */
> #ifdef HAVE_LIBUUID
> do {
> - uuid_generate(sbi.uuid);
> - } while (uuid_is_null(sbi.uuid));
> + uuid_generate(sbi->uuid);
> + } while (uuid_is_null(sbi->uuid));
> #endif
> }
>
> @@ -531,11 +533,12 @@ int main(int argc, char **argv)
> struct timeval t;
> char uuid_str[37] = "not available";
> struct erofs_device erofs_dev;
> + struct erofs_sb_info sbi;
>
> erofs_init_global_configure();
> - erofs_mkfs_default_options();
> + erofs_mkfs_default_options(&sbi);
>
> - err = mkfs_parse_options_cfg(argc, argv);
> + err = mkfs_parse_options_cfg(&sbi, argc, argv);
> erofs_show_progs(argc, argv);
> if (err) {
> if (err == -EINVAL)
> @@ -620,7 +623,7 @@ int main(int argc, char **argv)
> goto exit;
> }
>
> - err = z_erofs_compress_init(erofs_dev, sb_bh);
> + err = z_erofs_compress_init(erofs_dev, &sbi, sb_bh);
> if (err) {
> erofs_err("Failed to initialize compressor: %s",
> erofs_strerror(err));
> @@ -634,20 +637,20 @@ int main(int argc, char **argv)
>
> erofs_inode_manager_init();
>
> - err = erofs_build_shared_xattrs_from_path(cfg.c_src_path);
> + err = erofs_build_shared_xattrs_from_path(cfg.c_src_path, &sbi);
> if (err) {
> erofs_err("Failed to build shared xattrs: %s",
> erofs_strerror(err));
> goto exit;
> }
>
> - root_inode = erofs_mkfs_build_tree_from_path(erofs_dev, NULL, cfg.c_src_path);
> + root_inode = erofs_mkfs_build_tree_from_path(erofs_dev, &sbi, NULL, cfg.c_src_path);
> if (IS_ERR(root_inode)) {
> err = PTR_ERR(root_inode);
> goto exit;
> }
>
> - root_nid = erofs_lookupnid(root_inode);
> + root_nid = erofs_lookupnid(&sbi, root_inode);
> erofs_iput(root_inode);
>
> if (cfg.c_chunkbits) {
> @@ -657,7 +660,7 @@ int main(int argc, char **argv)
> goto exit;
> }
>
> - err = erofs_mkfs_update_super_block(sb_bh, root_nid, &nblocks);
> + err = erofs_mkfs_update_super_block(&sbi, sb_bh, root_nid, &nblocks);
> if (err)
> goto exit;
>
> --
> 2.34.0.rc2.393.gf8c9666880-goog
>
More information about the Linux-erofs
mailing list