[PATCH 2/4] erofs-utils: remove global sbi
Huang Jianan
jnhuang at linux.alibaba.com
Fri Sep 9 12:18:14 AEST 2022
Remove global sbi which will make erofs-utils more library friendly.
Signed-off-by: Huang Jianan <jnhuang at linux.alibaba.com>
---
dump/main.c | 71 ++++++++++++++++-------------
fsck/main.c | 55 +++++++++++++----------
fuse/main.c | 42 +++++++++++-------
include/erofs/blobchunk.h | 4 +-
include/erofs/cache.h | 2 +-
include/erofs/compress.h | 3 +-
include/erofs/config.h | 5 ++-
include/erofs/decompress.h | 1 +
include/erofs/dir.h | 4 +-
include/erofs/inode.h | 3 +-
include/erofs/internal.h | 25 +++++------
include/erofs/xattr.h | 8 ++--
lib/blobchunk.c | 17 +++----
lib/cache.c | 4 +-
lib/compress.c | 71 +++++++++++++++--------------
lib/compressor.h | 1 +
lib/compressor_lz4.c | 2 +-
lib/compressor_lz4hc.c | 2 +-
lib/config.c | 17 +++++--
lib/data.c | 21 +++++----
lib/decompress.c | 2 +-
lib/dir.c | 17 ++++---
lib/inode.c | 68 ++++++++++++++++------------
lib/io.c | 2 +
lib/namei.c | 19 +++++---
lib/super.c | 38 ++++++++--------
lib/xattr.c | 40 ++++++++++-------
lib/zmap.c | 26 ++++++-----
mkfs/main.c | 91 ++++++++++++++++++++------------------
29 files changed, 382 insertions(+), 279 deletions(-)
diff --git a/dump/main.c b/dump/main.c
index 07fa151..586302b 100644
--- a/dump/main.c
+++ b/dump/main.c
@@ -152,10 +152,10 @@ static int erofsdump_parse_options_cfg(int argc, char **argv)
usage();
exit(0);
case 3:
- err = blob_open_ro(sbi.dev, optarg);
+ err = blob_open_ro(cfg.sbi->dev, optarg);
if (err)
return err;
- ++sbi.extra_devices;
+ ++cfg.sbi->extra_devices;
break;
case 4:
dumpcfg.inode_path = optarg;
@@ -281,7 +281,10 @@ static int erofsdump_readdir(struct erofs_dir_context *ctx)
{
int err;
erofs_off_t occupied_size = 0;
- struct erofs_inode vi = { .nid = ctx->de_nid };
+ struct erofs_inode vi = {
+ .sbi = ctx->sbi,
+ .nid = ctx->de_nid,
+ };
err = erofs_read_inode_from_disk(&vi);
if (err) {
@@ -307,6 +310,7 @@ static int erofsdump_readdir(struct erofs_dir_context *ctx)
/* XXXX: the dir depth should be restricted in order to avoid loops */
if (S_ISDIR(vi.i_mode)) {
struct erofs_dir_context nctx = {
+ .sbi = ctx->sbi,
.flags = ctx->dir ? EROFS_READDIR_VALID_PNID : 0,
.pnid = ctx->dir ? ctx->dir->nid : 0,
.dir = &vi,
@@ -326,7 +330,7 @@ static int erofsdump_map_blocks(struct erofs_inode *inode,
return erofs_map_blocks(inode, map, flags);
}
-static void erofsdump_show_fileinfo(bool show_extent)
+static void erofsdump_show_fileinfo(struct erofs_sb_info *sbi, bool show_extent)
{
const char *ext_fmt[] = {
"%4d: %8" PRIu64 "..%8" PRIu64 " | %7" PRIu64 " : %10" PRIu64 "..%10" PRIu64 " | %7" PRIu64 "\n",
@@ -335,11 +339,14 @@ static void erofsdump_show_fileinfo(bool show_extent)
int err, i;
erofs_off_t size;
u16 access_mode;
- struct erofs_inode inode = { .nid = dumpcfg.nid };
char path[PATH_MAX];
char access_mode_str[] = "rwxrwxrwx";
char timebuf[128] = {0};
unsigned int extent_count = 0;
+ struct erofs_inode inode = {
+ .sbi = sbi,
+ .nid = dumpcfg.nid,
+ };
struct erofs_map_blocks map = {
.index = UINT_MAX,
.m_la = 0,
@@ -366,7 +373,7 @@ static void erofsdump_show_fileinfo(bool show_extent)
return;
}
- err = erofs_get_pathname(inode.nid, path, sizeof(path));
+ err = erofs_get_pathname(sbi, inode.nid, path, sizeof(path));
if (err < 0) {
erofs_err("file path not found @ nid %llu", inode.nid | 0ULL);
return;
@@ -396,6 +403,7 @@ static void erofsdump_show_fileinfo(bool show_extent)
if (dumpcfg.show_subdirectories) {
struct erofs_dir_context ctx = {
+ .sbi = sbi,
.flags = EROFS_READDIR_VALID_PNID,
.pnid = inode.nid,
.dir = &inode,
@@ -431,7 +439,7 @@ static void erofsdump_show_fileinfo(bool show_extent)
.m_deviceid = map.m_deviceid,
.m_pa = map.m_pa,
};
- err = erofs_map_dev(&sbi, &mdev);
+ err = erofs_map_dev(sbi, &mdev);
if (err) {
erofs_err("failed to map device");
return;
@@ -531,15 +539,16 @@ static void erofsdump_file_statistic(void)
stats.compress_rate);
}
-static void erofsdump_print_statistic(void)
+static void erofsdump_print_statistic(struct erofs_sb_info *sbi)
{
int err;
struct erofs_dir_context ctx = {
+ .sbi = sbi,
.flags = 0,
.pnid = 0,
.dir = NULL,
.cb = erofsdump_dirent_iter,
- .de_nid = sbi.root_nid,
+ .de_nid = sbi->root_nid,
.dname = "",
.de_namelen = 0,
};
@@ -559,36 +568,36 @@ static void erofsdump_print_statistic(void)
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;
+ time_t time = sbi->build_time;
char uuid_str[37] = "not available";
int i = 0;
fprintf(stdout, "Filesystem magic number: 0x%04X\n",
EROFS_SUPER_MAGIC_V1);
fprintf(stdout, "Filesystem blocks: %llu\n",
- sbi.total_blocks | 0ULL);
+ sbi->total_blocks | 0ULL);
fprintf(stdout, "Filesystem inode metadata start block: %u\n",
- sbi.meta_blkaddr);
+ sbi->meta_blkaddr);
fprintf(stdout, "Filesystem shared xattr metadata start block: %u\n",
- sbi.xattr_blkaddr);
+ sbi->xattr_blkaddr);
fprintf(stdout, "Filesystem root nid: %llu\n",
- sbi.root_nid | 0ULL);
+ sbi->root_nid | 0ULL);
fprintf(stdout, "Filesystem inode count: %llu\n",
- sbi.inos | 0ULL);
+ sbi->inos | 0ULL);
fprintf(stdout, "Filesystem created: %s",
ctime(&time));
fprintf(stdout, "Filesystem features: ");
for (; i < ARRAY_SIZE(feature_lists); i++) {
u32 feat = le32_to_cpu(feature_lists[i].compat ?
- sbi.feature_compat :
- sbi.feature_incompat);
+ sbi->feature_compat :
+ sbi->feature_incompat);
if (feat & feature_lists[i].flag)
fprintf(stdout, "%s ", feature_lists[i].name);
}
#ifdef HAVE_LIBUUID
- uuid_unparse_lower(sbi.uuid, uuid_str);
+ uuid_unparse_lower(sbi->uuid, uuid_str);
#endif
fprintf(stdout, "\nFilesystem UUID: %s\n",
uuid_str);
@@ -597,14 +606,16 @@ static void erofsdump_show_superblock(void)
int main(int argc, char **argv)
{
int err;
+ struct erofs_sb_info *sbi;
erofs_init_configure();
- sbi.dev = erofs_init_dev();
- if (IS_ERR(sbi.dev)) {
- err = PTR_ERR(sbi.dev);
+ sbi = erofs_init_sbi();
+ if (IS_ERR(sbi)) {
+ err = PTR_ERR(sbi);
goto exit;
}
+ cfg.sbi = sbi;
err = erofsdump_parse_options_cfg(argc, argv);
if (err) {
@@ -613,13 +624,13 @@ int main(int argc, char **argv)
goto exit_blob_close;
}
- err = dev_open_ro(sbi.dev, cfg.c_img_path);
+ err = dev_open_ro(sbi->dev, cfg.c_img_path);
if (err) {
erofs_err("failed to open image file");
goto exit_blob_close;
}
- err = erofs_read_superblock();
+ err = erofs_read_superblock(sbi);
if (err) {
erofs_err("failed to read superblock");
goto exit_dev_close;
@@ -630,10 +641,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();
+ erofsdump_print_statistic(sbi);
if (dumpcfg.show_extent && !dumpcfg.show_inode) {
usage();
@@ -641,14 +652,14 @@ int main(int argc, char **argv)
}
if (dumpcfg.show_inode)
- erofsdump_show_fileinfo(dumpcfg.show_extent);
+ erofsdump_show_fileinfo(sbi, dumpcfg.show_extent);
exit_put_super:
- erofs_put_super();
+ erofs_put_super(sbi);
exit_dev_close:
- dev_close(sbi.dev);
+ dev_close(sbi->dev);
exit_blob_close:
- blob_closeall(sbi.dev);
+ blob_closeall(sbi->dev);
exit:
erofs_exit_configure();
return err;
diff --git a/fsck/main.c b/fsck/main.c
index 1c8f567..ddfbf82 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -15,7 +15,8 @@
#include "erofs/decompress.h"
#include "erofs/dir.h"
-static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid);
+static int erofsfsck_check_inode(struct erofs_sb_info *sbi,
+ erofs_nid_t pnid, erofs_nid_t nid);
struct erofsfsck_cfg {
u64 physical_blocks;
@@ -143,10 +144,10 @@ static int erofsfsck_parse_options_cfg(int argc, char **argv)
}
break;
case 3:
- ret = blob_open_ro(sbi.dev, optarg);
+ ret = blob_open_ro(cfg.sbi->dev, optarg);
if (ret)
return ret;
- ++sbi.extra_devices;
+ ++cfg.sbi->extra_devices;
break;
case 4:
fsckcfg.force = true;
@@ -256,14 +257,14 @@ static void erofsfsck_set_attributes(struct erofs_inode *inode, char *path)
}
}
-static int erofs_check_sb_chksum(void)
+static int erofs_check_sb_chksum(struct erofs_sb_info *sbi)
{
int ret;
u8 buf[EROFS_BLKSIZ];
u32 crc;
struct erofs_super_block *sb;
- ret = blk_read(sbi.dev, 0, buf, 0, 1);
+ ret = blk_read(sbi->dev, 0, buf, 0, 1);
if (ret) {
erofs_err("failed to read superblock to check checksum: %d",
ret);
@@ -274,9 +275,9 @@ static int erofs_check_sb_chksum(void)
sb->checksum = 0;
crc = erofs_crc32c(~0, (u8 *)sb, EROFS_BLKSIZ - EROFS_SUPER_OFFSET);
- if (crc != sbi.checksum) {
+ if (crc != sbi->checksum) {
erofs_err("superblock chksum doesn't match: saved(%08xh) calculated(%08xh)",
- sbi.checksum, crc);
+ sbi->checksum, crc);
fsckcfg.corrupted = true;
return -1;
}
@@ -291,7 +292,7 @@ static int erofs_verify_xattr(struct erofs_inode *inode)
unsigned int ofs, xattr_shared_count;
struct erofs_xattr_ibody_header *ih;
struct erofs_xattr_entry *entry;
- struct erofs_device *dev = sbi.dev;
+ struct erofs_device *dev = inode->sbi->dev;
int i, remaining = inode->xattr_isize, ret = 0;
char buf[EROFS_BLKSIZ];
@@ -309,7 +310,7 @@ static int erofs_verify_xattr(struct erofs_inode *inode)
}
}
- addr = iloc(inode->nid) + inode->inode_isize;
+ addr = iloc(inode->sbi, inode->nid) + inode->inode_isize;
ret = dev_read(dev, 0, buf, addr, xattr_hdr_size);
if (ret < 0) {
erofs_err("failed to read xattr header @ nid %llu: %d",
@@ -367,6 +368,7 @@ static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
struct erofs_map_blocks map = {
.index = UINT_MAX,
};
+ struct erofs_sb_info *sbi = inode->sbi;
struct erofs_map_dev mdev;
int ret = 0;
bool compressed;
@@ -432,7 +434,7 @@ static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
.m_deviceid = map.m_deviceid,
.m_pa = map.m_pa,
};
- ret = erofs_map_dev(&sbi, &mdev);
+ ret = erofs_map_dev(sbi, &mdev);
if (ret) {
erofs_err("failed to map device of m_pa %" PRIu64 ", m_deviceid %u @ nid %llu: %d",
map.m_pa, map.m_deviceid, inode->nid | 0ULL,
@@ -446,7 +448,7 @@ static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
BUG_ON(!buffer);
}
- ret = dev_read(sbi.dev, mdev.m_deviceid, raw, mdev.m_pa, map.m_plen);
+ ret = dev_read(sbi->dev, mdev.m_deviceid, raw, mdev.m_pa, map.m_plen);
if (ret < 0) {
erofs_err("failed to read data of m_pa %" PRIu64 ", m_plen %" PRIu64 " @ nid %llu: %d",
mdev.m_pa, map.m_plen, inode->nid | 0ULL,
@@ -456,6 +458,7 @@ static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
if (compressed) {
struct z_erofs_decompress_req rq = {
+ .sbi = sbi,
.in = raw,
.out = buffer,
.decodedskip = 0,
@@ -694,7 +697,8 @@ static int erofsfsck_dirent_iter(struct erofs_dir_context *ctx)
fsckcfg.extract_pos = curr_pos;
}
- ret = erofsfsck_check_inode(ctx->dir->nid, ctx->de_nid);
+ ret = erofsfsck_check_inode(ctx->dir->sbi,
+ ctx->dir->nid, ctx->de_nid);
if (fsckcfg.extract_path) {
fsckcfg.extract_path[prev_pos] = '\0';
@@ -703,7 +707,8 @@ static int erofsfsck_dirent_iter(struct erofs_dir_context *ctx)
return ret;
}
-static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid)
+static int erofsfsck_check_inode(struct erofs_sb_info *sbi,
+ erofs_nid_t pnid, erofs_nid_t nid)
{
int ret;
struct erofs_inode inode;
@@ -711,6 +716,7 @@ static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid)
erofs_dbg("check inode: nid(%llu)", nid | 0ULL);
inode.nid = nid;
+ inode.sbi = sbi;
ret = erofs_read_inode_from_disk(&inode);
if (ret) {
if (ret == -EIO)
@@ -756,6 +762,7 @@ verify:
/* XXXX: the dir depth should be restricted in order to avoid loops */
if (S_ISDIR(inode.i_mode)) {
struct erofs_dir_context ctx = {
+ .sbi = sbi,
.flags = EROFS_READDIR_VALID_PNID,
.pnid = pnid,
.dir = &inode,
@@ -779,14 +786,16 @@ out:
int main(int argc, char **argv)
{
int err;
+ struct erofs_sb_info *sbi;
erofs_init_configure();
- sbi.dev = erofs_init_dev();
- if (IS_ERR(sbi.dev)) {
- err = PTR_ERR(sbi.dev);
+ sbi = erofs_init_sbi();
+ if (IS_ERR(sbi)) {
+ err = PTR_ERR(sbi);
goto exit;
}
+ cfg.sbi = sbi;
fsckcfg.physical_blocks = 0;
fsckcfg.logical_blocks = 0;
@@ -809,24 +818,24 @@ int main(int argc, char **argv)
goto exit_blob_close;
}
- err = dev_open_ro(sbi.dev, cfg.c_img_path);
+ err = dev_open_ro(sbi->dev, cfg.c_img_path);
if (err) {
erofs_err("failed to open image file");
goto exit_blob_close;
}
- err = erofs_read_superblock();
+ err = erofs_read_superblock(sbi);
if (err) {
erofs_err("failed to read superblock");
goto exit_dev_close;
}
- if (erofs_sb_has_sb_chksum() && erofs_check_sb_chksum()) {
+ if (erofs_sb_has_sb_chksum(sbi) && erofs_check_sb_chksum(sbi)) {
erofs_err("failed to verify superblock checksum");
goto exit_put_super;
}
- err = erofsfsck_check_inode(sbi.root_nid, sbi.root_nid);
+ err = erofsfsck_check_inode(sbi, sbi->root_nid, sbi->root_nid);
if (fsckcfg.corrupted) {
if (!fsckcfg.extract_path)
erofs_err("Found some filesystem corruption");
@@ -849,11 +858,11 @@ int main(int argc, char **argv)
}
exit_put_super:
- erofs_put_super();
+ erofs_put_super(sbi);
exit_dev_close:
- dev_close(sbi.dev);
+ dev_close(sbi->dev);
exit_blob_close:
- blob_closeall(sbi.dev);
+ blob_closeall(sbi->dev);
exit:
erofs_exit_configure();
return err ? 1 : 0;
diff --git a/fuse/main.c b/fuse/main.c
index ee86e50..edabdff 100644
--- a/fuse/main.c
+++ b/fuse/main.c
@@ -39,8 +39,10 @@ int erofsfuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
off_t offset, struct fuse_file_info *fi)
{
int ret;
- struct erofs_inode dir;
+ struct erofs_sb_info *sbi = fuse_get_context()->private_data;
+ struct erofs_inode dir = { .sbi = sbi };
struct erofsfuse_dir_context ctx = {
+ .ctx.sbi = sbi,
.ctx.dir = &dir,
.ctx.cb = erofsfuse_fill_dentries,
.filler = filler,
@@ -69,7 +71,7 @@ int erofsfuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
static void *erofsfuse_init(struct fuse_conn_info *info)
{
erofs_info("Using FUSE protocol %d.%d", info->proto_major, info->proto_minor);
- return NULL;
+ return fuse_get_context()->private_data;
}
static int erofsfuse_open(const char *path, struct fuse_file_info *fi)
@@ -84,7 +86,8 @@ static int erofsfuse_open(const char *path, struct fuse_file_info *fi)
static int erofsfuse_getattr(const char *path, struct stat *stbuf)
{
- struct erofs_inode vi = {};
+ struct erofs_sb_info *sbi = fuse_get_context()->private_data;
+ struct erofs_inode vi = { .sbi = sbi };
int ret;
erofs_dbg("getattr(%s)", path);
@@ -111,7 +114,8 @@ static int erofsfuse_read(const char *path, char *buffer,
struct fuse_file_info *fi)
{
int ret;
- struct erofs_inode vi;
+ struct erofs_sb_info *sbi = fuse_get_context()->private_data;
+ struct erofs_inode vi = { .sbi = sbi };
erofs_dbg("path:%s size=%zd offset=%llu", path, size, (long long)offset);
@@ -146,7 +150,8 @@ static int erofsfuse_getxattr(const char *path, const char *name, char *value,
size_t size)
{
int ret;
- struct erofs_inode vi;
+ struct erofs_sb_info *sbi = fuse_get_context()->private_data;
+ struct erofs_inode vi = { .sbi = sbi };
erofs_dbg("getxattr(%s): name=%s size=%llu", path, name, size);
@@ -160,7 +165,8 @@ static int erofsfuse_getxattr(const char *path, const char *name, char *value,
static int erofsfuse_listxattr(const char *path, char *list, size_t size)
{
int ret;
- struct erofs_inode vi;
+ struct erofs_sb_info *sbi = fuse_get_context()->private_data;
+ struct erofs_inode vi = { .sbi = sbi };
erofs_dbg("listxattr(%s): size=%llu", path, size);
@@ -239,10 +245,10 @@ static int optional_opt_func(void *data, const char *arg, int key,
switch (key) {
case 1:
- ret = blob_open_ro(sbi.dev, arg + sizeof("--device=") - 1);
+ ret = blob_open_ro(cfg.sbi->dev, arg + sizeof("--device=") - 1);
if (ret)
return -1;
- ++sbi.extra_devices;
+ ++cfg.sbi->extra_devices;
return 0;
case FUSE_OPT_KEY_NONOPT:
if (fusecfg.mountpoint)
@@ -293,15 +299,17 @@ int main(int argc, char *argv[])
{
int ret;
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
+ struct erofs_sb_info *sbi;
erofs_init_configure();
printf("%s %s\n", basename(argv[0]), cfg.c_version);
- sbi.dev = erofs_init_dev();
- if (IS_ERR(sbi.dev)) {
- ret = PTR_ERR(sbi.dev);
+ sbi = erofs_init_sbi();
+ if (IS_ERR(sbi)) {
+ ret = PTR_ERR(sbi);
goto err;
}
+ cfg.sbi = sbi;
#if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE)
if (signal(SIGSEGV, signal_handle_sigsegv) == SIG_ERR) {
@@ -326,24 +334,24 @@ int main(int argc, char *argv[])
cfg.c_offset = fusecfg.offset;
erofsfuse_dumpcfg();
- ret = dev_open_ro(sbi.dev, fusecfg.disk);
+ ret = dev_open_ro(sbi->dev, fusecfg.disk);
if (ret) {
fprintf(stderr, "failed to open: %s\n", fusecfg.disk);
goto err_fuse_free_args;
}
- ret = erofs_read_superblock();
+ ret = erofs_read_superblock(sbi);
if (ret) {
fprintf(stderr, "failed to read erofs super block\n");
goto err_dev_close;
}
- ret = fuse_main(args.argc, args.argv, &erofs_ops, NULL);
+ ret = fuse_main(args.argc, args.argv, &erofs_ops, sbi);
- erofs_put_super();
+ erofs_put_super(sbi);
err_dev_close:
- blob_closeall(sbi.dev);
- dev_close(sbi.dev);
+ blob_closeall(sbi->dev);
+ dev_close(sbi->dev);
err_fuse_free_args:
fuse_opt_free_args(&args);
err:
diff --git a/include/erofs/blobchunk.h b/include/erofs/blobchunk.h
index 49cb7bf..82426b7 100644
--- a/include/erofs/blobchunk.h
+++ b/include/erofs/blobchunk.h
@@ -16,10 +16,10 @@ extern "C"
int erofs_blob_write_chunk_indexes(struct erofs_inode *inode, erofs_off_t off);
int erofs_blob_write_chunked_file(struct erofs_inode *inode);
-int erofs_blob_remap(void);
+int erofs_blob_remap(struct erofs_sb_info *sbi);
void erofs_blob_exit(void);
int erofs_blob_init(const char *blobfile_path);
-int erofs_generate_devtable(void);
+int erofs_generate_devtable(struct erofs_sb_info *sbi);
#ifdef __cplusplus
}
diff --git a/include/erofs/cache.h b/include/erofs/cache.h
index e7aec2b..c11d676 100644
--- a/include/erofs/cache.h
+++ b/include/erofs/cache.h
@@ -96,7 +96,7 @@ static inline bool erofs_bh_flush_generic_end(struct erofs_buffer_head *bh)
return true;
}
-struct erofs_buffer_head *erofs_buffer_init(void);
+struct erofs_buffer_head *erofs_buffer_init(struct erofs_sb_info *sbi);
int erofs_bh_balloon(struct erofs_buffer_head *bh, erofs_off_t incr);
struct erofs_buffer_head *erofs_balloc(struct erofs_device *dev,
diff --git a/include/erofs/compress.h b/include/erofs/compress.h
index 24f6204..b2c1fda 100644
--- a/include/erofs/compress.h
+++ b/include/erofs/compress.h
@@ -20,7 +20,8 @@ extern "C"
void z_erofs_drop_inline_pcluster(struct erofs_inode *inode);
int erofs_write_compressed_file(struct erofs_inode *inode);
-int z_erofs_compress_init(struct erofs_buffer_head *bh);
+int z_erofs_compress_init(struct erofs_sb_info *sbi,
+ struct erofs_buffer_head *bh);
int z_erofs_compress_exit(void);
const char *z_erofs_list_available_compressors(unsigned int i);
diff --git a/include/erofs/config.h b/include/erofs/config.h
index 6c96664..1129989 100644
--- a/include/erofs/config.h
+++ b/include/erofs/config.h
@@ -14,6 +14,7 @@ extern "C"
#include "defs.h"
#include "err.h"
+#include "internal.h"
enum {
@@ -77,6 +78,8 @@ struct erofs_configure {
/* offset when reading multi partition images */
u64 c_offset;
+
+ struct erofs_sb_info *sbi;
};
extern struct erofs_configure cfg;
@@ -85,7 +88,7 @@ void erofs_init_configure(void);
void erofs_show_config(void);
void erofs_exit_configure(void);
-struct erofs_device *erofs_init_dev(void);
+struct erofs_sb_info *erofs_init_sbi(void);
void erofs_set_fs_root(const char *rootdir);
const char *erofs_fspath(const char *fullpath);
diff --git a/include/erofs/decompress.h b/include/erofs/decompress.h
index 82bf7b8..dd7eee2 100644
--- a/include/erofs/decompress.h
+++ b/include/erofs/decompress.h
@@ -14,6 +14,7 @@ extern "C"
#include "internal.h"
struct z_erofs_decompress_req {
+ struct erofs_sb_info *sbi;
char *in, *out;
/*
diff --git a/include/erofs/dir.h b/include/erofs/dir.h
index 74bffb5..cd257c4 100644
--- a/include/erofs/dir.h
+++ b/include/erofs/dir.h
@@ -39,6 +39,7 @@ typedef int (*erofs_readdir_cb)(struct erofs_dir_context *);
* the callback context. |de_namelen| is the exact dirent name length.
*/
struct erofs_dir_context {
+ struct erofs_sb_info *sbi;
/*
* During execution of |erofs_iterate_dir|, the function needs to
* read the values inside |erofs_inode* dir|. So it is important
@@ -62,7 +63,8 @@ struct erofs_dir_context {
/* Iterate over inodes that are in directory */
int erofs_iterate_dir(struct erofs_dir_context *ctx, bool fsck);
/* Get a full pathname of the inode NID */
-int erofs_get_pathname(erofs_nid_t nid, char *buf, size_t size);
+int erofs_get_pathname(struct erofs_sb_info *sbi, erofs_nid_t nid,
+ char *buf, size_t size);
#ifdef __cplusplus
}
diff --git a/include/erofs/inode.h b/include/erofs/inode.h
index 79b8d89..f76c675 100644
--- a/include/erofs/inode.h
+++ b/include/erofs/inode.h
@@ -20,7 +20,8 @@ unsigned char erofs_ftype_to_dtype(unsigned int filetype);
void erofs_inode_manager_init(void);
unsigned int erofs_iput(struct erofs_inode *inode);
erofs_nid_t erofs_lookupnid(struct erofs_inode *inode);
-struct erofs_inode *erofs_mkfs_build_tree_from_path(struct erofs_inode *parent,
+struct erofs_inode *erofs_mkfs_build_tree_from_path(struct erofs_sb_info *sbi,
+ struct erofs_inode *parent,
const char *path);
#ifdef __cplusplus
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index c4b36e9..98cfed1 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -112,26 +112,23 @@ struct erofs_sb_info {
};
};
-/* 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) \
-static inline bool erofs_sb_has_##name(void) \
+static inline bool erofs_sb_has_##name(struct erofs_sb_info *sbi) \
{ \
- return sbi.feature_##compat & EROFS_FEATURE_##feature; \
+ return sbi->feature_##compat & EROFS_FEATURE_##feature; \
} \
-static inline void erofs_sb_set_##name(void) \
+static inline void erofs_sb_set_##name(struct erofs_sb_info *sbi) \
{ \
- sbi.feature_##compat |= EROFS_FEATURE_##feature; \
+ sbi->feature_##compat |= EROFS_FEATURE_##feature; \
} \
-static inline void erofs_sb_clear_##name(void) \
+static inline void erofs_sb_clear_##name(struct erofs_sb_info *sbi) \
{ \
- sbi.feature_##compat &= ~EROFS_FEATURE_##feature; \
+ sbi->feature_##compat &= ~EROFS_FEATURE_##feature; \
}
EROFS_FEATURE_FUNCS(lz4_0padding, incompat, INCOMPAT_LZ4_0PADDING)
@@ -156,6 +153,7 @@ struct erofs_inode {
};
unsigned int i_count;
struct erofs_inode *i_parent;
+ struct erofs_sb_info *sbi;
umode_t i_mode;
erofs_off_t i_size;
@@ -246,6 +244,7 @@ static inline unsigned int erofs_inode_datalayout(unsigned int value)
struct erofs_dentry {
struct list_head d_child; /* child of parent list */
+ struct erofs_sb_info *sbi;
unsigned int type;
char name[EROFS_NAME_LEN];
@@ -328,8 +327,8 @@ struct erofs_map_dev {
};
/* super.c */
-int erofs_read_superblock(void);
-void erofs_put_super(void);
+int erofs_read_superblock(struct erofs_sb_info *sbi);
+void erofs_put_super(struct erofs_sb_info *sbi);
/* namei.c */
int erofs_read_inode_from_disk(struct erofs_inode *vi);
diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index a0528c0..0b63439 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -24,9 +24,10 @@ static inline unsigned int inlinexattr_header_size(struct erofs_inode *vi)
sizeof(u32) * vi->xattr_shared_count;
}
-static inline erofs_blk_t xattrblock_addr(unsigned int xattr_id)
+static inline erofs_blk_t xattrblock_addr(struct erofs_sb_info *sbi,
+ unsigned int xattr_id)
{
- return sbi.xattr_blkaddr +
+ return sbi->xattr_blkaddr +
xattr_id * sizeof(__u32) / EROFS_BLKSIZ;
}
@@ -68,7 +69,8 @@ static inline unsigned int xattrblock_offset(unsigned int xattr_id)
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(struct erofs_sb_info *sbi,
+ const char *path);
#ifdef __cplusplus
}
diff --git a/lib/blobchunk.c b/lib/blobchunk.c
index d11d7db..b91a0cf 100644
--- a/lib/blobchunk.c
+++ b/lib/blobchunk.c
@@ -104,6 +104,7 @@ static int erofs_blob_hashmap_cmp(const void *a, const void *b,
int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
erofs_off_t off)
{
+ struct erofs_device *dev = inode->sbi->dev;
struct erofs_inode_chunk_index idx = {0};
erofs_blk_t extent_start = EROFS_NULL_ADDR;
erofs_blk_t extent_end, extents_blks;
@@ -158,7 +159,7 @@ int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
erofs_droid_blocklist_write_extent(inode, extent_start, extents_blks,
first_extent, true);
- return dev_write(sbi.dev, inode->chunkindexes, off, inode->extent_isize);
+ return dev_write(dev, inode->chunkindexes, off, inode->extent_isize);
}
int erofs_blob_write_chunked_file(struct erofs_inode *inode)
@@ -212,9 +213,9 @@ err:
return ret;
}
-int erofs_blob_remap(void)
+int erofs_blob_remap(struct erofs_sb_info *sbi)
{
- struct erofs_device *dev = sbi.dev;
+ struct erofs_device *dev = sbi->dev;
struct erofs_buffer_head *bh;
ssize_t length;
erofs_off_t pos_in, pos_out;
@@ -281,22 +282,22 @@ int erofs_blob_init(const char *blobfile_path)
return 0;
}
-int erofs_generate_devtable(void)
+int erofs_generate_devtable(struct erofs_sb_info *sbi)
{
struct erofs_deviceslot dis;
if (!multidev)
return 0;
- bh_devt = erofs_balloc(sbi.dev, DEVT, sizeof(dis), 0, 0);
+ bh_devt = erofs_balloc(sbi->dev, DEVT, sizeof(dis), 0, 0);
if (IS_ERR(bh_devt))
return PTR_ERR(bh_devt);
dis = (struct erofs_deviceslot) {};
erofs_mapbh(bh_devt->block);
bh_devt->op = &erofs_skip_write_bhops;
- sbi.devt_slotoff = erofs_btell(bh_devt, false) / EROFS_DEVT_SLOT_SIZE;
- sbi.extra_devices = 1;
- erofs_sb_set_device_table();
+ sbi->devt_slotoff = erofs_btell(bh_devt, false) / EROFS_DEVT_SLOT_SIZE;
+ sbi->extra_devices = 1;
+ erofs_sb_set_device_table(sbi);
return 0;
}
diff --git a/lib/cache.c b/lib/cache.c
index 60b0ee6..478ac17 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -63,10 +63,10 @@ const struct erofs_bhops erofs_buf_write_bhops = {
};
/* return buffer_head of erofs super block (with size 0) */
-struct erofs_buffer_head *erofs_buffer_init(void)
+struct erofs_buffer_head *erofs_buffer_init(struct erofs_sb_info *sbi)
{
int i, j;
- struct erofs_buffer_head *bh = erofs_balloc(sbi.dev, META, 0, 0, 0);
+ struct erofs_buffer_head *bh = erofs_balloc(sbi->dev, META, 0, 0, 0);
if (IS_ERR(bh))
return bh;
diff --git a/lib/compress.c b/lib/compress.c
index ded0399..4f8d763 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -30,6 +30,7 @@ struct z_erofs_vle_compress_ctx {
unsigned int compressedblks;
erofs_blk_t blkaddr; /* pointing to the next blkaddr */
u16 clusterofs;
+ struct erofs_inode *vi;
};
#define Z_EROFS_LEGACY_MAP_HEADER_SIZE \
@@ -93,7 +94,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()) {
+ if (d0 == 1 && erofs_sb_has_big_pcluster(ctx->vi->sbi)) {
type = Z_EROFS_VLE_CLUSTER_TYPE_NONHEAD;
di.di_u.delta[0] = cpu_to_le16(ctx->compressedblks |
Z_EROFS_VLE_DI_D0_CBLKCNT);
@@ -142,12 +143,13 @@ static void vle_write_indexes(struct z_erofs_vle_compress_ctx *ctx,
static int write_uncompressed_extent(struct z_erofs_vle_compress_ctx *ctx,
unsigned int *len, char *dst)
{
+ struct erofs_sb_info *sbi = ctx->vi->sbi;
int ret;
unsigned int count;
/* reset clusterofs to 0 if permitted */
- if (!erofs_sb_has_lz4_0padding() && ctx->clusterofs &&
- ctx->head >= ctx->clusterofs) {
+ if (!erofs_sb_has_lz4_0padding(sbi) &&
+ ctx->clusterofs && ctx->head >= ctx->clusterofs) {
ctx->head -= ctx->clusterofs;
*len += ctx->clusterofs;
ctx->clusterofs = 0;
@@ -161,7 +163,7 @@ static int write_uncompressed_extent(struct z_erofs_vle_compress_ctx *ctx,
erofs_dbg("Writing %u uncompressed data to block %u",
count, ctx->blkaddr);
- ret = blk_write(sbi.dev, dst, ctx->blkaddr, 1);
+ ret = blk_write(sbi->dev, dst, ctx->blkaddr, 1);
if (ret)
return ret;
return count;
@@ -307,7 +309,7 @@ nocompression:
DBG_BUGON(ctx->compressedblks * EROFS_BLKSIZ >= count);
/* zero out garbage trailing data for non-0padding */
- if (!erofs_sb_has_lz4_0padding())
+ if (!erofs_sb_has_lz4_0padding(ctx->vi->sbi))
memset(dst + ret, 0,
roundup(ret, EROFS_BLKSIZ) - ret);
else if (tailused)
@@ -317,8 +319,8 @@ nocompression:
erofs_dbg("Writing %u compressed data to %u of %u blocks",
count, ctx->blkaddr, ctx->compressedblks);
- ret = blk_write(sbi.dev, dst - padding, ctx->blkaddr,
- ctx->compressedblks);
+ ret = blk_write(inode->sbi->dev, dst - padding,
+ ctx->blkaddr, ctx->compressedblks);
if (ret)
return ret;
raw = false;
@@ -384,10 +386,10 @@ static void *write_compacted_indexes(u8 *out,
erofs_blk_t *blkaddr_ret,
unsigned int destsize,
unsigned int logical_clusterbits,
- bool final, bool *dummy_head)
+ bool final, bool *dummy_head,
+ bool update_blkaddr)
{
unsigned int vcnt, encodebits, pos, i, cblks;
- bool update_blkaddr;
erofs_blk_t blkaddr;
if (destsize == 4)
@@ -398,7 +400,6 @@ 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();
pos = 0;
for (i = 0; i < vcnt; ++i) {
@@ -463,7 +464,8 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
/* # of 8-byte units so that it can be aligned with 32 bytes */
unsigned int compacted_4b_initial, compacted_4b_end;
unsigned int compacted_2b;
- bool dummy_head;
+ struct erofs_sb_info *sbi = inode->sbi;
+ bool dummy_head, big_pcluster = erofs_sb_has_big_pcluster(sbi);
if (logical_clusterbits < LOG_BLOCK_SIZE || LOG_BLOCK_SIZE < 12)
return -EINVAL;
@@ -495,7 +497,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()) {
+ if (!big_pcluster) {
--blkaddr;
dummy_head = true;
}
@@ -505,7 +507,7 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
in = parse_legacy_indexes(cv, 2, in);
out = write_compacted_indexes(out, cv, &blkaddr,
4, logical_clusterbits, false,
- &dummy_head);
+ &dummy_head, big_pcluster);
compacted_4b_initial -= 2;
}
DBG_BUGON(compacted_4b_initial);
@@ -515,7 +517,7 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
in = parse_legacy_indexes(cv, 16, in);
out = write_compacted_indexes(out, cv, &blkaddr,
2, logical_clusterbits, false,
- &dummy_head);
+ &dummy_head, big_pcluster);
compacted_2b -= 16;
}
DBG_BUGON(compacted_2b);
@@ -525,7 +527,7 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
in = parse_legacy_indexes(cv, 2, in);
out = write_compacted_indexes(out, cv, &blkaddr,
4, logical_clusterbits, false,
- &dummy_head);
+ &dummy_head, big_pcluster);
compacted_4b_end -= 2;
}
@@ -535,7 +537,7 @@ int z_erofs_convert_to_compacted_format(struct erofs_inode *inode,
in = parse_legacy_indexes(cv, 1, in);
out = write_compacted_indexes(out, cv, &blkaddr,
4, logical_clusterbits, true,
- &dummy_head);
+ &dummy_head, big_pcluster);
}
inode->extent_isize = out - (u8 *)compressmeta;
return 0;
@@ -625,7 +627,7 @@ int erofs_write_compressed_file(struct erofs_inode *inode)
}
/* allocate main data buffer */
- bh = erofs_balloc(sbi.dev, DATA, 0, 0, 0);
+ bh = erofs_balloc(inode->sbi->dev, DATA, 0, 0, 0);
if (IS_ERR(bh)) {
ret = PTR_ERR(bh);
goto err_close;
@@ -640,7 +642,7 @@ int erofs_write_compressed_file(struct erofs_inode *inode)
inode->datalayout = EROFS_INODE_FLAT_COMPRESSION_LEGACY;
}
- if (erofs_sb_has_big_pcluster()) {
+ if (erofs_sb_has_big_pcluster(inode->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;
@@ -654,6 +656,7 @@ int erofs_write_compressed_file(struct erofs_inode *inode)
ctx.metacur = compressmeta + Z_EROFS_LEGACY_MAP_HEADER_SIZE;
ctx.head = ctx.tail = 0;
ctx.clusterofs = 0;
+ ctx.vi = inode;
remaining = inode->i_size;
while (remaining) {
@@ -743,13 +746,14 @@ static int erofs_get_compress_algorithm_id(const char *name)
return -ENOTSUP;
}
-int z_erofs_build_compr_cfgs(struct erofs_buffer_head *sb_bh)
+int z_erofs_build_compr_cfgs(struct erofs_sb_info *sbi,
+ struct erofs_buffer_head *sb_bh)
{
struct erofs_buffer_head *bh = sb_bh;
- struct erofs_device *dev = sbi.dev;
+ struct erofs_device *dev = sbi->dev;
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;
@@ -757,7 +761,7 @@ int z_erofs_build_compr_cfgs(struct erofs_buffer_head *sb_bh)
.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,
}
};
@@ -773,7 +777,7 @@ int z_erofs_build_compr_cfgs(struct erofs_buffer_head *sb_bh)
bh->op = &erofs_drop_directly_bhops;
}
#ifdef HAVE_LIBLZMA
- if (sbi.available_compr_algs & (1 << Z_EROFS_COMPRESSION_LZMA)) {
+ if (sbi->available_compr_algs & (1 << Z_EROFS_COMPRESSION_LZMA)) {
struct {
__le16 size;
struct z_erofs_lzma_cfgs lzma;
@@ -798,12 +802,15 @@ int z_erofs_build_compr_cfgs(struct erofs_buffer_head *sb_bh)
return ret;
}
-int z_erofs_compress_init(struct erofs_buffer_head *sb_bh)
+int z_erofs_compress_init(struct erofs_sb_info *sbi,
+ struct erofs_buffer_head *sb_bh)
{
+ int ret;
+
+ compresshandle.sbi = sbi;
/* initialize for primary compression algorithm */
- int ret = erofs_compressor_init(&compresshandle,
+ ret = erofs_compressor_init(&compresshandle,
cfg.c_compr_alg_master);
-
if (ret)
return ret;
@@ -813,7 +820,7 @@ int z_erofs_compress_init(struct erofs_buffer_head *sb_bh)
*/
if (!cfg.c_compr_alg_master ||
(cfg.c_legacy_compress && !strcmp(cfg.c_compr_alg_master, "lz4")))
- erofs_sb_clear_lz4_0padding();
+ erofs_sb_clear_lz4_0padding(sbi);
if (!cfg.c_compr_alg_master)
return 0;
@@ -841,15 +848,15 @@ int z_erofs_compress_init(struct erofs_buffer_head *sb_bh)
cfg.c_pclusterblks_max);
return -EINVAL;
}
- erofs_sb_set_big_pcluster();
+ erofs_sb_set_big_pcluster(sbi);
}
if (ret != Z_EROFS_COMPRESSION_LZ4)
- erofs_sb_set_compr_cfgs();
+ erofs_sb_set_compr_cfgs(sbi);
- if (erofs_sb_has_compr_cfgs()) {
- sbi.available_compr_algs |= 1 << ret;
- return z_erofs_build_compr_cfgs(sb_bh);
+ if (erofs_sb_has_compr_cfgs(sbi)) {
+ sbi->available_compr_algs |= 1 << ret;
+ return z_erofs_build_compr_cfgs(sbi, sb_bh);
}
return 0;
}
diff --git a/lib/compressor.h b/lib/compressor.h
index cf063f1..6b2401a 100644
--- a/lib/compressor.h
+++ b/lib/compressor.h
@@ -28,6 +28,7 @@ struct erofs_compressor {
struct erofs_compress {
const struct erofs_compressor *alg;
+ struct erofs_sb_info *sbi;
unsigned int compress_threshold;
unsigned int compression_level;
diff --git a/lib/compressor_lz4.c b/lib/compressor_lz4.c
index b6f6e7e..e507b70 100644
--- a/lib/compressor_lz4.c
+++ b/lib/compressor_lz4.c
@@ -33,7 +33,7 @@ static int compressor_lz4_exit(struct erofs_compress *c)
static int compressor_lz4_init(struct erofs_compress *c)
{
c->alg = &erofs_compressor_lz4;
- sbi.lz4_max_distance = LZ4_DISTANCE_MAX;
+ c->sbi->lz4_max_distance = LZ4_DISTANCE_MAX;
return 0;
}
diff --git a/lib/compressor_lz4hc.c b/lib/compressor_lz4hc.c
index eec1c84..f2120d8 100644
--- a/lib/compressor_lz4hc.c
+++ b/lib/compressor_lz4hc.c
@@ -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;
+ c->sbi->lz4_max_distance = LZ4_DISTANCE_MAX;
return 0;
}
diff --git a/lib/config.c b/lib/config.c
index 3cc1d22..53a54e8 100644
--- a/lib/config.c
+++ b/lib/config.c
@@ -15,7 +15,6 @@
#endif
struct erofs_configure cfg;
-struct erofs_sb_info sbi;
void erofs_init_configure(void)
{
@@ -55,18 +54,28 @@ void erofs_exit_configure(void)
#endif
if (cfg.c_img_path)
free(cfg.c_img_path);
+ if (cfg.sbi)
+ free(cfg.sbi);
}
-struct erofs_device *erofs_init_dev(void)
+struct erofs_sb_info *erofs_init_sbi(void)
{
struct erofs_device *dev;
+ struct erofs_sb_info *sbi;
+
dev = calloc(1, sizeof(struct erofs_device));
if (!dev)
return ERR_PTR(-ENOMEM);
-
dev->fd = -1;
- return dev;
+ sbi = calloc(1, sizeof(struct erofs_sb_info));
+ if (!dev) {
+ free(dev);
+ return ERR_PTR(-ENOMEM);
+ }
+ sbi->dev = dev;
+
+ return sbi;
}
static unsigned int fullpath_prefix; /* root directory prefix length */
diff --git a/lib/data.c b/lib/data.c
index abfa3f4..b87a505 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -33,7 +33,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(vi->sbi, vi->nid) + vi->inode_isize +
vi->xattr_isize + erofs_blkoff(map->m_la);
map->m_plen = inode->i_size - offset;
@@ -65,6 +65,8 @@ int erofs_map_blocks(struct erofs_inode *inode,
struct erofs_map_blocks *map, int flags)
{
struct erofs_inode *vi = inode;
+ struct erofs_sb_info *sbi = vi->sbi;
+ struct erofs_device *dev = vi->sbi->dev;
struct erofs_inode_chunk_index *idx;
u8 buf[EROFS_BLKSIZ];
u64 chunknr;
@@ -89,10 +91,10 @@ int erofs_map_blocks(struct erofs_inode *inode,
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(sbi.dev, 0, buf, erofs_blknr(pos), 1);
+ err = blk_read(dev, 0, buf, erofs_blknr(pos), 1);
if (err < 0)
return -EIO;
@@ -120,7 +122,7 @@ int erofs_map_blocks(struct erofs_inode *inode,
break;
default:
map->m_deviceid = le16_to_cpu(idx->device_id) &
- sbi.device_id_mask;
+ sbi->device_id_mask;
map->m_pa = blknr_to_addr(le32_to_cpu(idx->blkaddr));
map->m_flags = EROFS_MAP_MAPPED;
break;
@@ -161,6 +163,7 @@ int erofs_map_dev(struct erofs_sb_info *sbi, struct erofs_map_dev *map)
static int erofs_read_raw_data(struct erofs_inode *inode, char *buffer,
erofs_off_t size, erofs_off_t offset)
{
+ struct erofs_sb_info *sbi = inode->sbi;
struct erofs_map_blocks map = {
.index = UINT_MAX,
};
@@ -183,7 +186,7 @@ static int erofs_read_raw_data(struct erofs_inode *inode, char *buffer,
.m_deviceid = map.m_deviceid,
.m_pa = map.m_pa,
};
- ret = erofs_map_dev(&sbi, &mdev);
+ ret = erofs_map_dev(sbi, &mdev);
if (ret)
return ret;
@@ -208,7 +211,7 @@ static int erofs_read_raw_data(struct erofs_inode *inode, char *buffer,
map.m_la = ptr;
}
- ret = dev_read(sbi.dev, mdev.m_deviceid, estart, mdev.m_pa,
+ ret = dev_read(sbi->dev, mdev.m_deviceid, estart, mdev.m_pa,
eend - map.m_la);
if (ret < 0)
return -EIO;
@@ -225,6 +228,7 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer,
.index = UINT_MAX,
};
struct erofs_map_dev mdev;
+ struct erofs_sb_info *sbi = inode->sbi;
bool partial;
unsigned int bufsize = 0;
char *raw = NULL;
@@ -242,7 +246,7 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer,
mdev = (struct erofs_map_dev) {
.m_pa = map.m_pa,
};
- ret = erofs_map_dev(&sbi, &mdev);
+ ret = erofs_map_dev(sbi, &mdev);
if (ret) {
DBG_BUGON(1);
break;
@@ -283,11 +287,12 @@ static int z_erofs_read_data(struct erofs_inode *inode, char *buffer,
break;
}
}
- ret = dev_read(sbi.dev, mdev.m_deviceid, raw, mdev.m_pa, map.m_plen);
+ ret = dev_read(sbi->dev, mdev.m_deviceid, raw, mdev.m_pa, map.m_plen);
if (ret < 0)
break;
ret = z_erofs_decompress(&(struct z_erofs_decompress_req) {
+ .sbi = sbi,
.in = raw,
.out = buffer + end - offset,
.decodedskip = skip,
diff --git a/lib/decompress.c b/lib/decompress.c
index 1661f91..fc4e049 100644
--- a/lib/decompress.c
+++ b/lib/decompress.c
@@ -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()) {
+ if (erofs_sb_has_lz4_0padding(rq->sbi)) {
support_0padding = true;
while (!src[inputmargin & ~PAGE_MASK])
diff --git a/lib/dir.c b/lib/dir.c
index e6b9283..073d704 100644
--- a/lib/dir.c
+++ b/lib/dir.c
@@ -76,8 +76,8 @@ static int traverse_dirents(struct erofs_dir_context *ctx,
goto out;
}
ctx->flags |= EROFS_READDIR_DOTDOT_FOUND;
- if (sbi.root_nid == ctx->dir->nid) {
- ctx->pnid = sbi.root_nid;
+ if (ctx->sbi->root_nid == ctx->dir->nid) {
+ ctx->pnid = ctx->sbi->root_nid;
ctx->flags |= EROFS_READDIR_VALID_PNID;
}
if (fsck &&
@@ -203,7 +203,9 @@ static int erofs_get_pathname_iter(struct erofs_dir_context *ctx)
}
if (ctx->de_ftype == EROFS_FT_DIR || ctx->de_ftype == EROFS_FT_UNKNOWN) {
- struct erofs_inode dir = { .nid = ctx->de_nid };
+ struct erofs_inode dir = {
+ .sbi = ctx->sbi,
+ .nid = ctx->de_nid, };
ret = erofs_read_inode_from_disk(&dir);
if (ret) {
@@ -229,11 +231,16 @@ static int erofs_get_pathname_iter(struct erofs_dir_context *ctx)
return 0;
}
-int erofs_get_pathname(erofs_nid_t nid, char *buf, size_t size)
+int erofs_get_pathname(struct erofs_sb_info *sbi, erofs_nid_t nid,
+ char *buf, size_t size)
{
int ret;
- struct erofs_inode root = { .nid = sbi.root_nid };
+ struct erofs_inode root = {
+ .sbi = sbi,
+ .nid = sbi->root_nid,
+ };
struct erofs_get_pathname_context pathctx = {
+ .ctx.sbi = sbi,
.ctx.flags = 0,
.ctx.dir = &root,
.ctx.cb = erofs_get_pathname_iter,
diff --git a/lib/inode.c b/lib/inode.c
index 09cd79f..cc21fd1 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -130,6 +130,7 @@ struct erofs_dentry *erofs_d_alloc(struct erofs_inode *parent,
if (!d)
return ERR_PTR(-ENOMEM);
+ d->sbi = parent->sbi;
strncpy(d->name, name, EROFS_NAME_LEN - 1);
d->name[EROFS_NAME_LEN - 1] = '\0';
@@ -151,7 +152,8 @@ static int __allocate_inode_bh_data(struct erofs_inode *inode,
}
/* allocate main data buffer */
- bh = erofs_balloc(sbi.dev, DATA, blknr_to_addr(nblocks), 0, 0);
+ bh = erofs_balloc(inode->sbi->dev, DATA, blknr_to_addr(nblocks),
+ 0, 0);
if (IS_ERR(bh))
return PTR_ERR(bh);
@@ -278,7 +280,7 @@ static int write_dirblock(unsigned int q, struct erofs_dentry *head,
char buf[EROFS_BLKSIZ];
fill_dirblock(buf, EROFS_BLKSIZ, q, head, end);
- return blk_write(sbi.dev, buf, blkaddr, 1);
+ return blk_write(head->sbi->dev, buf, blkaddr, 1);
}
static int erofs_write_dir_file(struct erofs_inode *dir)
@@ -340,7 +342,8 @@ static int erofs_write_file_from_buffer(struct erofs_inode *inode, char *buf)
return ret;
if (nblocks)
- blk_write(sbi.dev, buf, inode->u.i_blkaddr, nblocks);
+ blk_write(inode->sbi->dev, buf, inode->u.i_blkaddr,
+ nblocks);
inode->idata_size = inode->i_size % EROFS_BLKSIZ;
if (inode->idata_size) {
inode->idata = malloc(inode->idata_size);
@@ -382,7 +385,8 @@ static int write_uncompressed_file_from_fd(struct erofs_inode *inode, int fd)
return -EAGAIN;
}
- ret = blk_write(sbi.dev, buf, inode->u.i_blkaddr + i, 1);
+ ret = blk_write(inode->sbi->dev, buf,
+ inode->u.i_blkaddr + i, 1);
if (ret)
return ret;
}
@@ -443,7 +447,7 @@ int erofs_write_file(struct erofs_inode *inode)
static bool erofs_bh_flush_write_inode(struct erofs_buffer_head *bh)
{
struct erofs_inode *const inode = bh->fsprivate;
- struct erofs_device *dev = sbi.dev;
+ struct erofs_device *dev = bh->block->dev;
const u16 icount = EROFS_INODE_XATTR_ICOUNT(inode->xattr_isize);
erofs_off_t off = erofs_btell(bh, false);
union {
@@ -584,7 +588,8 @@ static int erofs_prepare_tail_block(struct erofs_inode *inode)
bh = inode->bh_data;
if (!bh) {
- bh = erofs_balloc(sbi.dev, DATA, EROFS_BLKSIZ, 0, 0);
+ bh = erofs_balloc(inode->sbi->dev, DATA, EROFS_BLKSIZ,
+ 0, 0);
if (IS_ERR(bh))
return PTR_ERR(bh);
bh->op = &erofs_skip_write_bhops;
@@ -607,6 +612,7 @@ static int erofs_prepare_inode_buffer(struct erofs_inode *inode)
{
unsigned int inodesize;
struct erofs_buffer_head *bh, *ibh;
+ struct erofs_sb_info *sbi = inode->sbi;
DBG_BUGON(inode->bh || inode->bh_inline);
@@ -632,7 +638,7 @@ static int erofs_prepare_inode_buffer(struct erofs_inode *inode)
inode->datalayout = EROFS_INODE_FLAT_PLAIN;
}
- bh = erofs_balloc(sbi.dev, INODE, inodesize, 0, inode->idata_size);
+ bh = erofs_balloc(sbi->dev, INODE, inodesize, 0, inode->idata_size);
if (bh == ERR_PTR(-ENOSPC)) {
int ret;
@@ -645,7 +651,7 @@ noinline:
ret = erofs_prepare_tail_block(inode);
if (ret)
return ret;
- bh = erofs_balloc(sbi.dev, INODE, inodesize, 0, 0);
+ bh = erofs_balloc(sbi->dev, INODE, inodesize, 0, 0);
if (IS_ERR(bh))
return PTR_ERR(bh);
DBG_BUGON(inode->bh_inline);
@@ -657,7 +663,7 @@ noinline:
erofs_dbg("Inline %scompressed data (%u bytes) to %s",
inode->compressed_idata ? "" : "un",
inode->idata_size, inode->i_srcpath);
- erofs_sb_set_ztailpacking();
+ erofs_sb_set_ztailpacking(sbi);
} else {
inode->datalayout = EROFS_INODE_FLAT_INLINE;
erofs_dbg("Inline tail-end data (%u bytes) to %s",
@@ -685,7 +691,7 @@ static bool erofs_bh_flush_write_inline(struct erofs_buffer_head *bh)
const erofs_off_t off = erofs_btell(bh, false);
int ret;
- ret = dev_write(sbi.dev, inode->idata, off, inode->idata_size);
+ ret = dev_write(bh->block->dev, inode->idata, off, inode->idata_size);
if (ret)
return false;
@@ -704,7 +710,7 @@ static struct erofs_bhops erofs_write_inline_bhops = {
static int erofs_write_tail_end(struct erofs_inode *inode)
{
struct erofs_buffer_head *bh, *ibh;
- struct erofs_device *dev = sbi.dev;
+ struct erofs_sb_info *sbi = inode->sbi;
bh = inode->bh_data;
@@ -727,20 +733,20 @@ static int erofs_write_tail_end(struct erofs_inode *inode)
pos = erofs_btell(bh, true) - EROFS_BLKSIZ;
/* 0'ed data should be padded at head for 0padding conversion */
- if (erofs_sb_has_lz4_0padding() && inode->compressed_idata) {
+ if (erofs_sb_has_lz4_0padding(sbi) && inode->compressed_idata) {
zero_pos = pos;
pos += EROFS_BLKSIZ - inode->idata_size;
} else {
/* pad 0'ed data for the other cases */
zero_pos = pos + inode->idata_size;
}
- ret = dev_write(dev, inode->idata, pos, inode->idata_size);
+ ret = dev_write(sbi->dev, inode->idata, pos, inode->idata_size);
if (ret)
return ret;
DBG_BUGON(inode->idata_size > EROFS_BLKSIZ);
if (inode->idata_size < EROFS_BLKSIZ) {
- ret = dev_fillzero(dev, zero_pos,
+ ret = dev_fillzero(sbi->dev, zero_pos,
EROFS_BLKSIZ - inode->idata_size,
false);
if (ret)
@@ -767,6 +773,8 @@ out:
static bool erofs_should_use_inode_extended(struct erofs_inode *inode)
{
+ struct erofs_sb_info *sbi = inode->sbi;
+
if (cfg.c_force_inodeversion == FORCE_INODE_EXTENDED)
return true;
if (inode->i_size > UINT_MAX)
@@ -777,8 +785,8 @@ static bool erofs_should_use_inode_extended(struct erofs_inode *inode)
return true;
if (inode->i_nlink > USHRT_MAX)
return true;
- if ((inode->i_mtime != sbi.build_time ||
- inode->i_mtime_nsec != sbi.build_time_nsec) &&
+ if ((inode->i_mtime != sbi->build_time ||
+ inode->i_mtime_nsec != sbi->build_time_nsec) &&
!cfg.c_ignore_mtime)
return true;
return false;
@@ -850,6 +858,7 @@ static int erofs_fill_inode(struct erofs_inode *inode,
struct stat64 *st,
const char *path)
{
+ struct erofs_sb_info *sbi = inode->sbi;
int err = erofs_droid_inode_fsconfig(inode, st, path);
if (err)
@@ -871,11 +880,11 @@ static int erofs_fill_inode(struct erofs_inode *inode,
switch (cfg.c_timeinherit) {
case TIMESTAMP_CLAMPING:
- if (inode->i_mtime < sbi.build_time)
+ if (inode->i_mtime < sbi->build_time)
break;
case TIMESTAMP_FIXED:
- inode->i_mtime = sbi.build_time;
- inode->i_mtime_nsec = sbi.build_time_nsec;
+ inode->i_mtime = sbi->build_time;
+ inode->i_mtime_nsec = sbi->build_time_nsec;
default:
break;
}
@@ -921,7 +930,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;
@@ -929,7 +938,8 @@ static struct erofs_inode *erofs_new_inode(void)
if (!inode)
return ERR_PTR(-ENOMEM);
- inode->i_ino[0] = sbi.inos++; /* inode serial number */
+ inode->sbi = sbi;
+ inode->i_ino[0] = sbi->inos++; /* inode serial number */
inode->i_count = 1;
init_list_head(&inode->i_subdirs);
@@ -938,7 +948,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;
@@ -964,7 +975,7 @@ 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;
@@ -990,7 +1001,7 @@ 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);
+ rootdir->sbi->meta_blkaddr = erofs_blknr(meta_offset);
rootdir->nid = (off - meta_offset) >> EROFS_ISLOTBITS;
}
@@ -1005,7 +1016,7 @@ 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(inode->sbi->meta_blkaddr);
DBG_BUGON(off < meta_offset);
return inode->nid = (off - meta_offset) >> EROFS_ISLOTBITS;
}
@@ -1132,7 +1143,7 @@ static struct erofs_inode *erofs_mkfs_build_tree(struct erofs_inode *dir)
sizeof("Processing ...") - 1);
erofs_update_progressinfo("Processing %s ...", trimmed);
free(trimmed);
- d->inode = erofs_mkfs_build_tree_from_path(dir, buf);
+ d->inode = erofs_mkfs_build_tree_from_path(dir->sbi, dir, buf);
if (IS_ERR(d->inode)) {
ret = PTR_ERR(d->inode);
fail:
@@ -1160,10 +1171,11 @@ err:
return ERR_PTR(ret);
}
-struct erofs_inode *erofs_mkfs_build_tree_from_path(struct erofs_inode *parent,
+struct erofs_inode *erofs_mkfs_build_tree_from_path(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;
diff --git a/lib/io.c b/lib/io.c
index 2b9811e..d4d127e 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -10,6 +10,7 @@
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
+#include <stdlib.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include "erofs/io.h"
@@ -52,6 +53,7 @@ void dev_close(struct erofs_device *dev)
dev->name = NULL;
dev->fd = -1;
dev->size = 0;
+ free(dev);
}
int dev_open(struct erofs_device *dev, const char *devname)
diff --git a/lib/namei.c b/lib/namei.c
index bb14d30..8612b81 100644
--- a/lib/namei.c
+++ b/lib/namei.c
@@ -28,8 +28,9 @@ int erofs_read_inode_from_disk(struct erofs_inode *vi)
char buf[sizeof(struct erofs_inode_extended)];
struct erofs_inode_compact *dic;
struct erofs_inode_extended *die;
- struct erofs_device *dev = sbi.dev;
- const erofs_off_t inode_loc = iloc(vi->nid);
+ struct erofs_sb_info *sbi = vi->sbi;
+ struct erofs_device *dev = vi->sbi->dev;
+ const erofs_off_t inode_loc = iloc(sbi, vi->nid);
ret = dev_read(dev, 0, buf, inode_loc, sizeof(*dic));
if (ret < 0)
@@ -115,8 +116,8 @@ int erofs_read_inode_from_disk(struct erofs_inode *vi)
vi->i_gid = le16_to_cpu(dic->i_gid);
vi->i_nlink = le16_to_cpu(dic->i_nlink);
- vi->i_mtime = sbi.build_time;
- vi->i_mtime_nsec = sbi.build_time_nsec;
+ vi->i_mtime = sbi->build_time;
+ vi->i_mtime_nsec = sbi->build_time_nsec;
vi->i_size = le32_to_cpu(dic->i_size);
if (vi->datalayout == EROFS_INODE_CHUNK_BASED)
@@ -183,6 +184,7 @@ struct erofs_dirent *find_target_dirent(erofs_nid_t pnid,
}
struct nameidata {
+ struct erofs_sb_info *sbi;
erofs_nid_t nid;
unsigned int ftype;
};
@@ -193,7 +195,10 @@ int erofs_namei(struct nameidata *nd,
erofs_nid_t nid = nd->nid;
int ret;
char buf[EROFS_BLKSIZ];
- struct erofs_inode vi = { .nid = nid };
+ struct erofs_inode vi = {
+ .sbi = nd->sbi,
+ .nid = nid,
+ };
erofs_off_t offset;
ret = erofs_read_inode_from_disk(&vi);
@@ -235,7 +240,7 @@ int erofs_namei(struct nameidata *nd,
static int link_path_walk(const char *name, struct nameidata *nd)
{
- nd->nid = sbi.root_nid;
+ nd->nid = nd->sbi->root_nid;
while (*name == '/')
name++;
@@ -265,7 +270,7 @@ static int link_path_walk(const char *name, struct nameidata *nd)
int erofs_ilookup(const char *path, struct erofs_inode *vi)
{
int ret;
- struct nameidata nd;
+ struct nameidata nd = { .sbi = vi->sbi };
ret = link_path_walk(path, &nd);
if (ret)
diff --git a/lib/super.c b/lib/super.c
index 8727161..fcd27b6 100644
--- a/lib/super.c
+++ b/lib/super.c
@@ -31,7 +31,7 @@ static int erofs_init_devices(struct erofs_sb_info *sbi,
sbi->total_blocks = sbi->primarydevice_blocks;
- if (!erofs_sb_has_device_table())
+ if (!erofs_sb_has_device_table(sbi))
ondisk_extradevs = 0;
else
ondisk_extradevs = le16_to_cpu(dsb->extra_devices);
@@ -66,14 +66,14 @@ static int erofs_init_devices(struct erofs_sb_info *sbi,
return 0;
}
-int erofs_read_superblock(void)
+int erofs_read_superblock(struct erofs_sb_info *sbi)
{
char data[EROFS_BLKSIZ];
struct erofs_super_block *dsb;
unsigned int blkszbits;
int ret;
- ret = blk_read(sbi.dev, 0, data, 0, 1);
+ ret = blk_read(sbi->dev, 0, data, 0, 1);
if (ret < 0) {
erofs_err("cannot read erofs superblock: %d", ret);
return -EIO;
@@ -86,7 +86,7 @@ int erofs_read_superblock(void)
return ret;
}
- sbi.feature_compat = le32_to_cpu(dsb->feature_compat);
+ sbi->feature_compat = le32_to_cpu(dsb->feature_compat);
blkszbits = dsb->blkszbits;
/* 9(512 bytes) + LOG_SECTORS_PER_BLOCK == LOG_BLOCK_SIZE */
@@ -96,26 +96,26 @@ int erofs_read_superblock(void)
return ret;
}
- if (!check_layout_compatibility(&sbi, dsb))
+ if (!check_layout_compatibility(sbi, dsb))
return ret;
- sbi.primarydevice_blocks = le32_to_cpu(dsb->blocks);
- sbi.meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
- sbi.xattr_blkaddr = le32_to_cpu(dsb->xattr_blkaddr);
- sbi.islotbits = EROFS_ISLOTBITS;
- sbi.root_nid = le16_to_cpu(dsb->root_nid);
- sbi.inos = le64_to_cpu(dsb->inos);
- sbi.checksum = le32_to_cpu(dsb->checksum);
+ sbi->primarydevice_blocks = le32_to_cpu(dsb->blocks);
+ sbi->meta_blkaddr = le32_to_cpu(dsb->meta_blkaddr);
+ sbi->xattr_blkaddr = le32_to_cpu(dsb->xattr_blkaddr);
+ sbi->islotbits = EROFS_ISLOTBITS;
+ sbi->root_nid = le16_to_cpu(dsb->root_nid);
+ sbi->inos = le64_to_cpu(dsb->inos);
+ sbi->checksum = le32_to_cpu(dsb->checksum);
- sbi.build_time = le64_to_cpu(dsb->build_time);
- sbi.build_time_nsec = le32_to_cpu(dsb->build_time_nsec);
+ sbi->build_time = le64_to_cpu(dsb->build_time);
+ sbi->build_time_nsec = le32_to_cpu(dsb->build_time_nsec);
- memcpy(&sbi.uuid, dsb->uuid, sizeof(dsb->uuid));
- return erofs_init_devices(&sbi, dsb);
+ memcpy(sbi->uuid, dsb->uuid, sizeof(dsb->uuid));
+ return erofs_init_devices(sbi, dsb);
}
-void erofs_put_super(void)
+void erofs_put_super(struct erofs_sb_info *sbi)
{
- if (sbi.devs)
- free(sbi.devs);
+ if (sbi->devs)
+ free(sbi->devs);
}
diff --git a/lib/xattr.c b/lib/xattr.c
index e0bf922..2496004 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -549,7 +549,8 @@ static void erofs_cleanxattrs(bool sharedxattrs)
static bool erofs_bh_flush_write_shared_xattrs(struct erofs_buffer_head *bh)
{
void *buf = bh->fsprivate;
- int err = dev_write(sbi.dev, buf, erofs_btell(bh, false), shared_xattrs_size);
+ int err = dev_write(bh->block->dev, buf, erofs_btell(bh, false),
+ shared_xattrs_size);
if (err)
return false;
@@ -579,7 +580,8 @@ static int comp_xattr_item(const void *a, const void *b)
return la > lb;
}
-int erofs_build_shared_xattrs_from_path(const char *path)
+int erofs_build_shared_xattrs_from_path(struct erofs_sb_info *sbi,
+ const char *path)
{
int ret;
struct erofs_buffer_head *bh;
@@ -609,7 +611,7 @@ int erofs_build_shared_xattrs_from_path(const char *path)
if (!buf)
return -ENOMEM;
- bh = erofs_balloc(sbi.dev, XATTR, shared_xattrs_size, 0, 0);
+ bh = erofs_balloc(sbi->dev, XATTR, shared_xattrs_size, 0, 0);
if (IS_ERR(bh)) {
free(buf);
return PTR_ERR(bh);
@@ -619,7 +621,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;
@@ -716,6 +718,7 @@ char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size)
}
struct xattr_iter {
+ struct erofs_sb_info *sbi;
char page[EROFS_BLKSIZ];
void *kaddr;
@@ -729,7 +732,8 @@ static int init_inode_xattrs(struct erofs_inode *vi)
struct xattr_iter it;
unsigned int i;
struct erofs_xattr_ibody_header *ih;
- struct erofs_device *dev = sbi.dev;
+ struct erofs_sb_info *sbi = vi->sbi;
+ struct erofs_device *dev = vi->sbi->dev;
int ret = 0;
/* the most case is that xattrs of this inode are initialized. */
@@ -757,8 +761,8 @@ static int init_inode_xattrs(struct erofs_inode *vi)
return -ENOATTR;
}
- it.blkaddr = erofs_blknr(iloc(vi->nid) + vi->inode_isize);
- it.ofs = erofs_blkoff(iloc(vi->nid) + vi->inode_isize);
+ it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize);
+ it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize);
ret = blk_read(dev, 0, it.page, it.blkaddr, 1);
if (ret < 0)
@@ -825,7 +829,7 @@ static inline int xattr_iter_fixup(struct xattr_iter *it)
it->blkaddr += erofs_blknr(it->ofs);
- ret = blk_read(sbi.dev, 0, it->page, it->blkaddr, 1);
+ ret = blk_read(it->sbi->dev, 0, it->page, it->blkaddr, 1);
if (ret < 0)
return -EIO;
@@ -837,6 +841,8 @@ static inline int xattr_iter_fixup(struct xattr_iter *it)
static int inline_xattr_iter_pre(struct xattr_iter *it,
struct erofs_inode *vi)
{
+ struct erofs_sb_info *sbi = vi->sbi;
+ struct erofs_device *dev = vi->sbi->dev;
unsigned int xattr_header_sz, inline_xattr_ofs;
int ret;
@@ -848,10 +854,10 @@ static int inline_xattr_iter_pre(struct xattr_iter *it,
inline_xattr_ofs = vi->inode_isize + xattr_header_sz;
- it->blkaddr = erofs_blknr(iloc(vi->nid) + inline_xattr_ofs);
- it->ofs = erofs_blkoff(iloc(vi->nid) + inline_xattr_ofs);
+ it->blkaddr = erofs_blknr(iloc(sbi, vi->nid) + inline_xattr_ofs);
+ it->ofs = erofs_blkoff(iloc(sbi, vi->nid) + inline_xattr_ofs);
- ret = blk_read(sbi.dev, 0, it->page, it->blkaddr, 1);
+ ret = blk_read(dev, 0, it->page, it->blkaddr, 1);
if (ret < 0)
return -EIO;
@@ -1038,17 +1044,18 @@ static int inline_getxattr(struct erofs_inode *vi, struct getxattr_iter *it)
static int shared_getxattr(struct erofs_inode *vi, struct getxattr_iter *it)
{
+ struct erofs_sb_info *sbi = vi->sbi;
unsigned int i;
int ret = -ENOATTR;
for (i = 0; i < vi->xattr_shared_count; ++i) {
erofs_blk_t blkaddr =
- xattrblock_addr(vi->xattr_shared_xattrs[i]);
+ xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]);
it->it.ofs = xattrblock_offset(vi->xattr_shared_xattrs[i]);
if (!i || blkaddr != it->it.blkaddr) {
- ret = blk_read(sbi.dev, 0, it->it.page, blkaddr, 1);
+ ret = blk_read(sbi->dev, 0, it->it.page, blkaddr, 1);
if (ret < 0)
return -EIO;
@@ -1091,6 +1098,7 @@ int erofs_getxattr(struct erofs_inode *vi, const char *name, char *buffer,
it.buffer = buffer;
it.buffer_size = buffer_size;
+ it.it.sbi = vi->sbi;
ret = inline_getxattr(vi, &it);
if (ret == -ENOATTR)
ret = shared_getxattr(vi, &it);
@@ -1178,16 +1186,17 @@ static int inline_listxattr(struct erofs_inode *vi, struct listxattr_iter *it)
static int shared_listxattr(struct erofs_inode *vi, struct listxattr_iter *it)
{
+ struct erofs_sb_info *sbi = vi->sbi;
unsigned int i;
int ret = 0;
for (i = 0; i < vi->xattr_shared_count; ++i) {
erofs_blk_t blkaddr =
- xattrblock_addr(vi->xattr_shared_xattrs[i]);
+ xattrblock_addr(sbi, vi->xattr_shared_xattrs[i]);
it->it.ofs = xattrblock_offset(vi->xattr_shared_xattrs[i]);
if (!i || blkaddr != it->it.blkaddr) {
- ret = blk_read(sbi.dev, 0, it->it.page, blkaddr, 1);
+ ret = blk_read(sbi->dev, 0, it->it.page, blkaddr, 1);
if (ret < 0)
return -EIO;
@@ -1218,6 +1227,7 @@ int erofs_listxattr(struct erofs_inode *vi, char *buffer, size_t buffer_size)
it.buffer_size = buffer_size;
it.buffer_ofs = 0;
+ it.it.sbi = vi->sbi;
ret = inline_listxattr(vi, &it);
if (ret < 0 && ret != -ENOATTR)
return ret;
diff --git a/lib/zmap.c b/lib/zmap.c
index 6e5a5d4..0ddc922 100644
--- a/lib/zmap.c
+++ b/lib/zmap.c
@@ -16,8 +16,10 @@ static int z_erofs_do_map_blocks(struct erofs_inode *vi,
int z_erofs_fill_inode(struct erofs_inode *vi)
{
- if (!erofs_sb_has_big_pcluster() &&
- !erofs_sb_has_ztailpacking() &&
+ struct erofs_sb_info *sbi = vi->sbi;
+
+ if (!erofs_sb_has_big_pcluster(sbi) &&
+ !erofs_sb_has_ztailpacking(sbi) &&
vi->datalayout == EROFS_INODE_FLAT_COMPRESSION_LEGACY) {
vi->z_advise = 0;
vi->z_algorithmtype[0] = 0;
@@ -31,6 +33,7 @@ int z_erofs_fill_inode(struct erofs_inode *vi)
static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
{
+ struct erofs_sb_info *sbi = vi->sbi;
int ret;
erofs_off_t pos;
struct z_erofs_map_header *h;
@@ -39,12 +42,13 @@ static int z_erofs_fill_inode_lazy(struct erofs_inode *vi)
if (vi->flags & EROFS_I_Z_INITED)
return 0;
- DBG_BUGON(!erofs_sb_has_big_pcluster() &&
- !erofs_sb_has_ztailpacking() &&
+ DBG_BUGON(!erofs_sb_has_big_pcluster(sbi) &&
+ !erofs_sb_has_ztailpacking(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(vi->sbi, vi->nid) + vi->inode_isize +
+ vi->xattr_isize, 8);
- ret = dev_read(sbi.dev, 0, buf, pos, sizeof(buf));
+ ret = dev_read(sbi->dev, 0, buf, pos, sizeof(buf));
if (ret < 0)
return -EIO;
@@ -111,7 +115,7 @@ static int z_erofs_reload_indexes(struct z_erofs_maprecorder *m,
if (map->index == eblk)
return 0;
- ret = blk_read(sbi.dev, 0, mpage, eblk, 1);
+ ret = blk_read(m->inode->sbi->dev, 0, mpage, eblk, 1);
if (ret < 0)
return -EIO;
@@ -124,7 +128,7 @@ static int legacy_load_cluster_from_disk(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(vi->sbi, vi->nid);
const erofs_off_t pos =
Z_EROFS_VLE_LEGACY_INDEX_ALIGN(ibase + vi->inode_isize +
vi->xattr_isize) +
@@ -322,9 +326,9 @@ static int compacted_load_cluster_from_disk(struct z_erofs_maprecorder *m,
{
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 +
- vi->xattr_isize, 8) +
- sizeof(struct z_erofs_map_header);
+ const erofs_off_t ebase = round_up(iloc(vi->sbi, vi->nid) +
+ vi->inode_isize + vi->xattr_isize, 8) +
+ sizeof(struct z_erofs_map_header);
const unsigned int totalidx = BLK_ROUND_UP(vi->i_size);
unsigned int compacted_4b_initial, compacted_2b;
unsigned int amortizedshift;
diff --git a/mkfs/main.c b/mkfs/main.c
index e3ad9d9..3e8a1c0 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -176,7 +176,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();
+ erofs_sb_clear_sb_chksum(cfg.sbi);
}
if (MATCH_EXTENTED_OPT("noinline_data", token, keylen)) {
@@ -265,7 +265,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, cfg.sbi->uuid)) {
erofs_err("invalid UUID %s", optarg);
return -EINVAL;
}
@@ -373,7 +373,7 @@ static int mkfs_parse_options_cfg(int argc, char *argv[])
optarg);
return -EINVAL;
}
- erofs_sb_set_chunked_file();
+ erofs_sb_set_chunked_file(cfg.sbi);
break;
case 12:
quiet = true;
@@ -456,24 +456,25 @@ 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),
- .extra_devices = cpu_to_le16(sbi.extra_devices),
- .devt_slotoff = cpu_to_le16(sbi.devt_slotoff),
+ .extra_devices = cpu_to_le16(sbi->extra_devices),
+ .devt_slotoff = cpu_to_le16(sbi->devt_slotoff),
};
const unsigned int sb_blksize =
round_up(EROFS_SUPER_END, EROFS_BLKSIZ);
@@ -482,12 +483,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())
- 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) {
@@ -502,13 +503,13 @@ int erofs_mkfs_update_super_block(struct erofs_buffer_head *bh,
return 0;
}
-static int erofs_mkfs_superblock_csum_set(void)
+static int erofs_mkfs_superblock_csum_set(struct erofs_sb_info *sbi)
{
int ret;
u8 buf[EROFS_BLKSIZ];
u32 crc;
struct erofs_super_block *sb;
- struct erofs_device *dev = sbi.dev;
+ struct erofs_device *dev = sbi->dev;
ret = blk_read(dev, 0, buf, 0, 1);
if (ret) {
@@ -551,15 +552,15 @@ static void erofs_mkfs_default_options(void)
{
cfg.c_showprogress = true;
cfg.c_legacy_compress = false;
- sbi.feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;
- sbi.feature_compat = EROFS_FEATURE_COMPAT_SB_CHKSUM |
+ cfg.sbi->feature_incompat = EROFS_FEATURE_INCOMPAT_LZ4_0PADDING;
+ cfg.sbi->feature_compat = EROFS_FEATURE_COMPAT_SB_CHKSUM |
EROFS_FEATURE_COMPAT_MTIME;
/* generate a default uuid first */
#ifdef HAVE_LIBUUID
do {
- uuid_generate(sbi.uuid);
- } while (uuid_is_null(sbi.uuid));
+ uuid_generate(cfg.sbi->uuid);
+ } while (uuid_is_null(cfg.sbi->uuid));
#endif
}
@@ -599,6 +600,7 @@ void erofs_show_progs(int argc, char *argv[])
int main(int argc, char **argv)
{
int err = 0;
+ struct erofs_sb_info *sbi;
struct erofs_buffer_head *sb_bh;
struct erofs_inode *root_inode;
erofs_nid_t root_nid;
@@ -609,9 +611,10 @@ int main(int argc, char **argv)
erofs_init_configure();
- sbi.dev = erofs_init_dev();
- if (IS_ERR(sbi.dev))
+ sbi = erofs_init_sbi();
+ if (IS_ERR(sbi))
return 1;
+ cfg.sbi = sbi;
erofs_mkfs_default_options();
err = mkfs_parse_options_cfg(argc, argv);
@@ -645,14 +648,14 @@ int main(int argc, char **argv)
}
if (cfg.c_unix_timestamp != -1) {
- sbi.build_time = cfg.c_unix_timestamp;
- sbi.build_time_nsec = 0;
+ sbi->build_time = cfg.c_unix_timestamp;
+ sbi->build_time_nsec = 0;
} else if (!gettimeofday(&t, NULL)) {
- sbi.build_time = t.tv_sec;
- sbi.build_time_nsec = t.tv_usec;
+ sbi->build_time = t.tv_sec;
+ sbi->build_time_nsec = t.tv_usec;
}
- err = dev_open(sbi.dev, cfg.c_img_path);
+ err = dev_open(sbi->dev, cfg.c_img_path);
if (err) {
usage();
return 1;
@@ -671,7 +674,7 @@ int main(int argc, char **argv)
}
#endif
erofs_show_config();
- if (erofs_sb_has_chunked_file())
+ if (erofs_sb_has_chunked_file(sbi))
erofs_warn("EXPERIMENTAL chunked file feature in use. Use at your own risk!");
if (cfg.c_ztailpacking)
erofs_warn("EXPERIMENTAL compressed inline data feature in use. Use at your own risk!");
@@ -680,7 +683,7 @@ int main(int argc, char **argv)
if (cfg.c_random_pclusterblks)
srand(time(NULL));
#endif
- sb_bh = erofs_buffer_init();
+ sb_bh = erofs_buffer_init(sbi);
if (IS_ERR(sb_bh)) {
err = PTR_ERR(sb_bh);
erofs_err("failed to initialize buffers: %s",
@@ -701,34 +704,34 @@ int main(int argc, char **argv)
goto exit;
}
- err = z_erofs_compress_init(sb_bh);
+ err = z_erofs_compress_init(sbi, sb_bh);
if (err) {
erofs_err("failed to initialize compressor: %s",
erofs_strerror(err));
goto exit;
}
- err = erofs_generate_devtable();
+ err = erofs_generate_devtable(sbi);
if (err) {
erofs_err("failed to generate device table: %s",
erofs_strerror(err));
goto exit;
}
#ifdef HAVE_LIBUUID
- uuid_unparse_lower(sbi.uuid, uuid_str);
+ uuid_unparse_lower(sbi->uuid, uuid_str);
#endif
erofs_info("filesystem UUID: %s", uuid_str);
erofs_inode_manager_init();
- err = erofs_build_shared_xattrs_from_path(cfg.c_src_path);
+ err = erofs_build_shared_xattrs_from_path(sbi, cfg.c_src_path);
if (err) {
erofs_err("failed to build shared xattrs: %s",
erofs_strerror(err));
goto exit;
}
- root_inode = erofs_mkfs_build_tree_from_path(NULL, cfg.c_src_path);
+ root_inode = erofs_mkfs_build_tree_from_path(sbi, NULL, cfg.c_src_path);
if (IS_ERR(root_inode)) {
err = PTR_ERR(root_inode);
goto exit;
@@ -739,29 +742,29 @@ int main(int argc, char **argv)
if (cfg.c_chunkbits) {
erofs_info("total metadata: %u blocks", erofs_mapbh(NULL));
- err = erofs_blob_remap();
+ err = erofs_blob_remap(sbi);
if (err)
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;
/* flush all remaining buffers */
- if (!erofs_bflush(sbi.dev, NULL))
+ if (!erofs_bflush(sbi->dev, NULL))
err = -EIO;
else
- err = dev_resize(sbi.dev, nblocks);
+ err = dev_resize(sbi->dev, nblocks);
- if (!err && erofs_sb_has_sb_chksum())
- err = erofs_mkfs_superblock_csum_set();
+ if (!err && erofs_sb_has_sb_chksum(sbi))
+ err = erofs_mkfs_superblock_csum_set(sbi);
exit:
z_erofs_compress_exit();
#ifdef WITH_ANDROID
erofs_droid_blocklist_fclose();
#endif
- dev_close(sbi.dev);
+ dev_close(sbi->dev);
erofs_cleanup_compress_hints();
erofs_cleanup_exclude_rules();
if (cfg.c_chunkbits)
--
2.34.1
More information about the Linux-erofs
mailing list