This updates all relevant function definitions and callers
to get rid of the global g_sbi, making it suitable for external
use in liberofs.

Signed-off-by: Hongzhen Luo <hongz...@linux.alibaba.com>
---
 include/erofs/cache.h    |  42 ++++++----
 include/erofs/internal.h |   5 +-
 lib/blobchunk.c          |  20 ++---
 lib/cache.c              | 162 +++++++++++++++++++++------------------
 lib/compress.c           |  40 +++++-----
 lib/inode.c              |  43 ++++++-----
 lib/super.c              |  21 ++---
 lib/xattr.c              |  10 +--
 mkfs/main.c              |  15 ++--
 9 files changed, 198 insertions(+), 160 deletions(-)

diff --git a/include/erofs/cache.h b/include/erofs/cache.h
index 288843e..16148ea 100644
--- a/include/erofs/cache.h
+++ b/include/erofs/cache.h
@@ -53,10 +53,20 @@ struct erofs_buffer_block {
        struct erofs_buffer_head buffers;
 };
 
-static inline const int get_alignsize(int type, int *type_ret)
-{
-       struct erofs_sb_info *sbi = &g_sbi;
+struct erofs_buffer_manager {
+       struct erofs_buffer_block blkh;
+       erofs_blk_t tail_blkaddr, erofs_metablkcnt;
+
+       /* buckets for all mapped buffer blocks to boost up allocation */
+       struct list_head mapped_buckets[META + 1][EROFS_MAX_BLOCK_SIZE];
 
+       /* last mapped buffer block to accelerate erofs_mapbh() */
+       struct erofs_buffer_block *last_mapped_block;
+};
+
+static inline const int get_alignsize(struct erofs_sb_info *sbi, int type,
+                                     int *type_ret)
+{
        if (type == DATA)
                return erofs_blksiz(sbi);
 
@@ -82,10 +92,10 @@ static inline const int get_alignsize(int type, int 
*type_ret)
 extern const struct erofs_bhops erofs_drop_directly_bhops;
 extern const struct erofs_bhops erofs_skip_write_bhops;
 
-static inline erofs_off_t erofs_btell(struct erofs_buffer_head *bh, bool end)
+static inline erofs_off_t erofs_btell(struct erofs_sb_info *sbi,
+                                     struct erofs_buffer_head *bh, bool end)
 {
        const struct erofs_buffer_block *bb = bh->block;
-       struct erofs_sb_info *sbi = &g_sbi;
 
        if (bb->blkaddr == NULL_ADDR)
                return NULL_ADDR_UL;
@@ -101,20 +111,26 @@ static inline int erofs_bh_flush_generic_end(struct 
erofs_buffer_head *bh)
        return 0;
 }
 
-void erofs_buffer_init(erofs_blk_t startblk);
-int erofs_bh_balloon(struct erofs_buffer_head *bh, erofs_off_t incr);
+void erofs_buffer_init(struct erofs_sb_info *sbi, erofs_blk_t startblk);
+int erofs_bh_balloon(struct erofs_sb_info *sbi, struct erofs_buffer_head *bh,
+                    erofs_off_t incr);
 
-struct erofs_buffer_head *erofs_balloc(int type, erofs_off_t size,
+struct erofs_buffer_head *erofs_balloc(struct erofs_sb_info *sbi,
+                                      int type, erofs_off_t size,
                                       unsigned int required_ext,
                                       unsigned int inline_ext);
-struct erofs_buffer_head *erofs_battach(struct erofs_buffer_head *bh,
+struct erofs_buffer_head *erofs_battach(struct erofs_sb_info *sbi,
+                                       struct erofs_buffer_head *bh,
                                        int type, unsigned int size);
 
-erofs_blk_t erofs_mapbh(struct erofs_buffer_block *bb);
-int erofs_bflush(struct erofs_buffer_block *bb);
+erofs_blk_t erofs_mapbh(struct erofs_sb_info *sbi,
+                       struct erofs_buffer_block *bb);
+int erofs_bflush(struct erofs_sb_info *sbi, struct erofs_buffer_block *bb);
 
-void erofs_bdrop(struct erofs_buffer_head *bh, bool tryrevoke);
-erofs_blk_t erofs_total_metablocks(void);
+void erofs_bdrop(struct erofs_sb_info *sbi, struct erofs_buffer_head *bh,
+                bool tryrevoke);
+erofs_blk_t erofs_total_metablocks(struct erofs_sb_info *sbi);
+void erofs_buffer_exit(struct erofs_sb_info *sbi);
 
 #ifdef __cplusplus
 }
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 5f70570..bad9f13 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -58,6 +58,7 @@ extern struct erofs_sb_info g_sbi;
        (roundup(addr, erofs_blksiz(sbi)) >> (sbi)->blkszbits)
 
 struct erofs_buffer_head;
+struct erofs_buffer_manager;
 
 struct erofs_device_info {
        u8 tag[64];
@@ -132,6 +133,8 @@ struct erofs_sb_info {
        struct erofs_mkfs_dfops *mkfs_dfops;
 #endif
        bool useqpl;
+
+       struct erofs_buffer_manager *bmngr;
 };
 
 #define EROFS_SUPER_END (EROFS_SUPER_OFFSET + sizeof(struct erofs_super_block))
@@ -402,7 +405,7 @@ int erofs_read_superblock(struct erofs_sb_info *sbi);
 void erofs_put_super(struct erofs_sb_info *sbi);
 int erofs_writesb(struct erofs_sb_info *sbi, struct erofs_buffer_head *sb_bh,
                  erofs_blk_t *blocks);
-struct erofs_buffer_head *erofs_reserve_sb(void);
+struct erofs_buffer_head *erofs_reserve_sb(struct erofs_sb_info *sbi);
 int erofs_enable_sb_chksum(struct erofs_sb_info *sbi, u32 *crc);
 
 /* namei.c */
diff --git a/lib/blobchunk.c b/lib/blobchunk.c
index 9af223d..1169288 100644
--- a/lib/blobchunk.c
+++ b/lib/blobchunk.c
@@ -496,8 +496,8 @@ int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi)
                unsigned int i, ret;
                erofs_blk_t nblocks;
 
-               nblocks = erofs_mapbh(NULL);
-               pos_out = erofs_btell(bh_devt, false);
+               nblocks = erofs_mapbh(sbi, NULL);
+               pos_out = erofs_btell(sbi, bh_devt, false);
                i = 0;
                do {
                        struct erofs_deviceslot dis = {
@@ -513,17 +513,17 @@ int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi)
                        nblocks += sbi->devs[i].blocks;
                } while (++i < sbi->extra_devices);
                bh_devt->op = &erofs_drop_directly_bhops;
-               erofs_bdrop(bh_devt, false);
+               erofs_bdrop(sbi, bh_devt, false);
                return 0;
        }
 
-       bh = erofs_balloc(DATA, datablob_size, 0, 0);
+       bh = erofs_balloc(sbi, DATA, datablob_size, 0, 0);
        if (IS_ERR(bh))
                return PTR_ERR(bh);
 
-       erofs_mapbh(bh->block);
+       erofs_mapbh(sbi, bh->block);
 
-       pos_out = erofs_btell(bh, false);
+       pos_out = erofs_btell(sbi, bh, false);
        remapped_base = erofs_blknr(sbi, pos_out);
        pos_out += sbi->bdev.offset;
        if (blobfile) {
@@ -535,7 +535,7 @@ int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi)
                ret = erofs_io_ftruncate(&sbi->bdev, pos_out + datablob_size);
        }
        bh->op = &erofs_drop_directly_bhops;
-       erofs_bdrop(bh, false);
+       erofs_bdrop(sbi, bh, false);
        return ret;
 }
 
@@ -626,15 +626,15 @@ int erofs_mkfs_init_devices(struct erofs_sb_info *sbi, 
unsigned int devices)
        if (!sbi->devs)
                return -ENOMEM;
 
-       bh_devt = erofs_balloc(DEVT,
+       bh_devt = erofs_balloc(sbi, DEVT,
                sizeof(struct erofs_deviceslot) * devices, 0, 0);
        if (IS_ERR(bh_devt)) {
                free(sbi->devs);
                return PTR_ERR(bh_devt);
        }
-       erofs_mapbh(bh_devt->block);
+       erofs_mapbh(sbi, bh_devt->block);
        bh_devt->op = &erofs_skip_write_bhops;
-       sbi->devt_slotoff = erofs_btell(bh_devt, false) / EROFS_DEVT_SLOT_SIZE;
+       sbi->devt_slotoff = erofs_btell(sbi, bh_devt, false) / 
EROFS_DEVT_SLOT_SIZE;
        sbi->extra_devices = devices;
        erofs_sb_set_device_table(sbi);
        return 0;
diff --git a/lib/cache.c b/lib/cache.c
index 69a3055..d0afc92 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -9,17 +9,6 @@
 #include <erofs/cache.h>
 #include "erofs/print.h"
 
-static struct erofs_buffer_block blkh = {
-       .list = LIST_HEAD_INIT(blkh.list),
-       .blkaddr = NULL_ADDR,
-};
-static erofs_blk_t tail_blkaddr, erofs_metablkcnt;
-
-/* buckets for all mapped buffer blocks to boost up allocation */
-static struct list_head mapped_buckets[META + 1][EROFS_MAX_BLOCK_SIZE];
-/* last mapped buffer block to accelerate erofs_mapbh() */
-static struct erofs_buffer_block *last_mapped_block = &blkh;
-
 static int erofs_bh_flush_drop_directly(struct erofs_buffer_head *bh)
 {
        return erofs_bh_flush_generic_end(bh);
@@ -38,39 +27,48 @@ const struct erofs_bhops erofs_skip_write_bhops = {
        .flush = erofs_bh_flush_skip_write,
 };
 
-void erofs_buffer_init(erofs_blk_t startblk)
+void erofs_buffer_init(struct erofs_sb_info *sbi, erofs_blk_t startblk)
 {
        int i, j;
 
-       for (i = 0; i < ARRAY_SIZE(mapped_buckets); i++)
-               for (j = 0; j < ARRAY_SIZE(mapped_buckets[0]); j++)
-                       init_list_head(&mapped_buckets[i][j]);
-       tail_blkaddr = startblk;
+       sbi->bmngr = malloc(sizeof(struct erofs_buffer_manager));
+       if (!sbi->bmngr) {
+               erofs_err("fail to prepare buffer manager");
+               return;
+       }
+       init_list_head(&sbi->bmngr->blkh.list);
+       sbi->bmngr->blkh.blkaddr = NULL_ADDR;
+       sbi->bmngr->last_mapped_block = &sbi->bmngr->blkh;
+
+       for (i = 0; i < ARRAY_SIZE(sbi->bmngr->mapped_buckets); i++)
+               for (j = 0; j < ARRAY_SIZE(sbi->bmngr->mapped_buckets[0]); j++)
+                       init_list_head(&sbi->bmngr->mapped_buckets[i][j]);
+       sbi->bmngr->tail_blkaddr = startblk;
 }
 
-static void erofs_bupdate_mapped(struct erofs_buffer_block *bb)
+static void erofs_bupdate_mapped(struct erofs_sb_info *sbi,
+                                struct erofs_buffer_block *bb)
 {
        struct list_head *bkt;
-       struct erofs_sb_info *sbi = &g_sbi;
 
        if (bb->blkaddr == NULL_ADDR)
                return;
 
-       bkt = mapped_buckets[bb->type] +
+       bkt = sbi->bmngr->mapped_buckets[bb->type] +
                (bb->buffers.off & (erofs_blksiz(sbi) - 1));
        list_del(&bb->mapped_list);
        list_add_tail(&bb->mapped_list, bkt);
 }
 
 /* return occupied bytes in specific buffer block if succeed */
-static int __erofs_battach(struct erofs_buffer_block *bb,
+static int __erofs_battach(struct erofs_sb_info *sbi,
+                          struct erofs_buffer_block *bb,
                           struct erofs_buffer_head *bh,
                           erofs_off_t incr,
                           unsigned int alignsize,
                           unsigned int extrasize,
                           bool dryrun)
 {
-       struct erofs_sb_info *sbi = &g_sbi;
        const unsigned int blksiz = erofs_blksiz(sbi);
        const unsigned int blkmask = blksiz - 1;
        erofs_off_t boff = bb->buffers.off;
@@ -87,7 +85,7 @@ static int __erofs_battach(struct erofs_buffer_block *bb,
 
                blkaddr = bb->blkaddr;
                if (blkaddr != NULL_ADDR) {
-                       tailupdate = (tail_blkaddr == blkaddr +
+                       tailupdate = (sbi->bmngr->tail_blkaddr == blkaddr +
                                      BLK_ROUND_UP(sbi, boff));
                        if (oob && !tailupdate)
                                return -EINVAL;
@@ -104,13 +102,15 @@ static int __erofs_battach(struct erofs_buffer_block *bb,
                bb->buffers.off = boff;
                /* need to update the tail_blkaddr */
                if (tailupdate)
-                       tail_blkaddr = blkaddr + BLK_ROUND_UP(sbi, boff);
-               erofs_bupdate_mapped(bb);
+                       sbi->bmngr->tail_blkaddr = blkaddr +
+                                               BLK_ROUND_UP(sbi, boff);
+               erofs_bupdate_mapped(sbi, bb);
        }
        return ((alignedoffset + incr - 1) & blkmask) + 1;
 }
 
-int erofs_bh_balloon(struct erofs_buffer_head *bh, erofs_off_t incr)
+int erofs_bh_balloon(struct erofs_sb_info *sbi, struct erofs_buffer_head *bh,
+                    erofs_off_t incr)
 {
        struct erofs_buffer_block *const bb = bh->block;
 
@@ -118,16 +118,16 @@ int erofs_bh_balloon(struct erofs_buffer_head *bh, 
erofs_off_t incr)
        if (bh->list.next != &bb->buffers.list)
                return -EINVAL;
 
-       return __erofs_battach(bb, NULL, incr, 1, 0, false);
+       return __erofs_battach(sbi, bb, NULL, incr, 1, 0, false);
 }
 
-static int erofs_bfind_for_attach(int type, erofs_off_t size,
+static int erofs_bfind_for_attach(struct erofs_sb_info *sbi,
+                                 int type, erofs_off_t size,
                                  unsigned int required_ext,
                                  unsigned int inline_ext,
                                  unsigned int alignsize,
                                  struct erofs_buffer_block **bbp)
 {
-       struct erofs_sb_info *sbi = &g_sbi;
        const unsigned int blksiz = erofs_blksiz(sbi);
        struct erofs_buffer_block *cur, *bb;
        unsigned int used0, used_before, usedmax, used;
@@ -153,7 +153,8 @@ static int erofs_bfind_for_attach(int type, erofs_off_t 
size,
        used_before = rounddown(blksiz -
                                (size + required_ext + inline_ext), alignsize);
        for (; used_before; --used_before) {
-               struct list_head *bt = mapped_buckets[type] + used_before;
+               struct list_head *bt = sbi->bmngr->mapped_buckets[type] +
+                                                               used_before;
 
                if (list_empty(bt))
                        continue;
@@ -162,7 +163,7 @@ static int erofs_bfind_for_attach(int type, erofs_off_t 
size,
 
                /* last mapped block can be expended, don't handle it here */
                if (list_next_entry(cur, list)->blkaddr == NULL_ADDR) {
-                       DBG_BUGON(cur != last_mapped_block);
+                       DBG_BUGON(cur != sbi->bmngr->last_mapped_block);
                        continue;
                }
 
@@ -170,7 +171,7 @@ static int erofs_bfind_for_attach(int type, erofs_off_t 
size,
                DBG_BUGON(cur->blkaddr == NULL_ADDR);
                DBG_BUGON(used_before != (cur->buffers.off & (blksiz - 1)));
 
-               ret = __erofs_battach(cur, NULL, size, alignsize,
+               ret = __erofs_battach(sbi, cur, NULL, size, alignsize,
                                      required_ext + inline_ext, true);
                if (ret < 0) {
                        DBG_BUGON(1);
@@ -188,10 +189,10 @@ static int erofs_bfind_for_attach(int type, erofs_off_t 
size,
 
 skip_mapped:
        /* try to start from the last mapped one, which can be expended */
-       cur = last_mapped_block;
-       if (cur == &blkh)
+       cur = sbi->bmngr->last_mapped_block;
+       if (cur == &sbi->bmngr->blkh)
                cur = list_next_entry(cur, list);
-       for (; cur != &blkh; cur = list_next_entry(cur, list)) {
+       for (; cur != &sbi->bmngr->blkh; cur = list_next_entry(cur, list)) {
                used_before = cur->buffers.off & (blksiz - 1);
 
                /* skip if buffer block is just full */
@@ -202,7 +203,7 @@ skip_mapped:
                if (cur->type != type)
                        continue;
 
-               ret = __erofs_battach(cur, NULL, size, alignsize,
+               ret = __erofs_battach(sbi, cur, NULL, size, alignsize,
                                      required_ext + inline_ext, true);
                if (ret < 0)
                        continue;
@@ -229,7 +230,8 @@ skip_mapped:
        return 0;
 }
 
-struct erofs_buffer_head *erofs_balloc(int type, erofs_off_t size,
+struct erofs_buffer_head *erofs_balloc(struct erofs_sb_info *sbi,
+                                      int type, erofs_off_t size,
                                       unsigned int required_ext,
                                       unsigned int inline_ext)
 {
@@ -237,7 +239,7 @@ struct erofs_buffer_head *erofs_balloc(int type, 
erofs_off_t size,
        struct erofs_buffer_head *bh;
        unsigned int alignsize;
 
-       int ret = get_alignsize(type, &type);
+       int ret = get_alignsize(sbi, type, &type);
 
        if (ret < 0)
                return ERR_PTR(ret);
@@ -246,7 +248,7 @@ struct erofs_buffer_head *erofs_balloc(int type, 
erofs_off_t size,
        alignsize = ret;
 
        /* try to find if we could reuse an allocated buffer block */
-       ret = erofs_bfind_for_attach(type, size, required_ext, inline_ext,
+       ret = erofs_bfind_for_attach(sbi, type, size, required_ext, inline_ext,
                                     alignsize, &bb);
        if (ret)
                return ERR_PTR(ret);
@@ -266,9 +268,10 @@ struct erofs_buffer_head *erofs_balloc(int type, 
erofs_off_t size,
                bb->buffers.off = 0;
                init_list_head(&bb->buffers.list);
                if (type == DATA)
-                       list_add(&bb->list, &last_mapped_block->list);
+                       list_add(&bb->list,
+                               &sbi->bmngr->last_mapped_block->list);
                else
-                       list_add_tail(&bb->list, &blkh.list);
+                       list_add_tail(&bb->list, &sbi->bmngr->blkh.list);
                init_list_head(&bb->mapped_list);
 
                bh = malloc(sizeof(struct erofs_buffer_head));
@@ -278,7 +281,7 @@ struct erofs_buffer_head *erofs_balloc(int type, 
erofs_off_t size,
                }
        }
 
-       ret = __erofs_battach(bb, bh, size, alignsize,
+       ret = __erofs_battach(sbi, bb, bh, size, alignsize,
                              required_ext + inline_ext, false);
        if (ret < 0) {
                free(bh);
@@ -287,13 +290,14 @@ struct erofs_buffer_head *erofs_balloc(int type, 
erofs_off_t size,
        return bh;
 }
 
-struct erofs_buffer_head *erofs_battach(struct erofs_buffer_head *bh,
+struct erofs_buffer_head *erofs_battach(struct erofs_sb_info *sbi,
+                                       struct erofs_buffer_head *bh,
                                        int type, unsigned int size)
 {
        struct erofs_buffer_block *const bb = bh->block;
        struct erofs_buffer_head *nbh;
        unsigned int alignsize;
-       int ret = get_alignsize(type, &type);
+       int ret = get_alignsize(sbi, type, &type);
 
        if (ret < 0)
                return ERR_PTR(ret);
@@ -307,7 +311,7 @@ struct erofs_buffer_head *erofs_battach(struct 
erofs_buffer_head *bh,
        if (!nbh)
                return ERR_PTR(-ENOMEM);
 
-       ret = __erofs_battach(bb, nbh, size, alignsize, 0, false);
+       ret = __erofs_battach(sbi, bb, nbh, size, alignsize, 0, false);
        if (ret < 0) {
                free(nbh);
                return ERR_PTR(ret);
@@ -315,61 +319,63 @@ struct erofs_buffer_head *erofs_battach(struct 
erofs_buffer_head *bh,
        return nbh;
 }
 
-static erofs_blk_t __erofs_mapbh(struct erofs_buffer_block *bb)
+static erofs_blk_t __erofs_mapbh(struct erofs_sb_info *sbi,
+                                struct erofs_buffer_block *bb)
 {
        erofs_blk_t blkaddr;
-       struct erofs_sb_info *sbi = &g_sbi;
 
        if (bb->blkaddr == NULL_ADDR) {
-               bb->blkaddr = tail_blkaddr;
-               last_mapped_block = bb;
-               erofs_bupdate_mapped(bb);
+               bb->blkaddr = sbi->bmngr->tail_blkaddr;
+               sbi->bmngr->last_mapped_block = bb;
+               erofs_bupdate_mapped(sbi, bb);
        }
 
        blkaddr = bb->blkaddr + BLK_ROUND_UP(sbi, bb->buffers.off);
-       if (blkaddr > tail_blkaddr)
-               tail_blkaddr = blkaddr;
+       if (blkaddr > sbi->bmngr->tail_blkaddr)
+               sbi->bmngr->tail_blkaddr = blkaddr;
 
        return blkaddr;
 }
 
-erofs_blk_t erofs_mapbh(struct erofs_buffer_block *bb)
+erofs_blk_t erofs_mapbh(struct erofs_sb_info *sbi,
+                       struct erofs_buffer_block *bb)
 {
-       struct erofs_buffer_block *t = last_mapped_block;
+       struct erofs_buffer_block *t = sbi->bmngr->last_mapped_block;
 
        if (bb && bb->blkaddr != NULL_ADDR)
                return bb->blkaddr;
        do {
                t = list_next_entry(t, list);
-               if (t == &blkh)
+               if (t == &sbi->bmngr->blkh)
                        break;
 
                DBG_BUGON(t->blkaddr != NULL_ADDR);
-               (void)__erofs_mapbh(t);
+               (void)__erofs_mapbh(sbi, t);
        } while (t != bb);
-       return tail_blkaddr;
+       return sbi->bmngr->tail_blkaddr;
 }
 
-static void erofs_bfree(struct erofs_buffer_block *bb)
+static void erofs_bfree(struct erofs_sb_info *sbi,
+                       struct erofs_buffer_block *bb)
 {
        DBG_BUGON(!list_empty(&bb->buffers.list));
 
-       if (bb == last_mapped_block)
-               last_mapped_block = list_prev_entry(bb, list);
+       if (bb == sbi->bmngr->last_mapped_block)
+               sbi->bmngr->last_mapped_block = list_prev_entry(bb, list);
 
        list_del(&bb->mapped_list);
        list_del(&bb->list);
        free(bb);
 }
 
-int erofs_bflush(struct erofs_buffer_block *bb)
+int erofs_bflush(struct erofs_sb_info *sbi,
+                struct erofs_buffer_block *bb)
 {
-       struct erofs_sb_info *sbi = &g_sbi;
        const unsigned int blksiz = erofs_blksiz(sbi);
        struct erofs_buffer_block *p, *n;
        erofs_blk_t blkaddr;
 
-       list_for_each_entry_safe(p, n, &blkh.list, list) {
+       list_for_each_entry_safe(p, n, &sbi->bmngr->blkh.list, list) {
                struct erofs_buffer_head *bh, *nbh;
                unsigned int padding;
                bool skip = false;
@@ -378,7 +384,7 @@ int erofs_bflush(struct erofs_buffer_block *bb)
                if (p == bb)
                        break;
 
-               blkaddr = __erofs_mapbh(p);
+               blkaddr = __erofs_mapbh(sbi, p);
 
                list_for_each_entry_safe(bh, nbh, &p->buffers.list, list) {
                        if (bh->op == &erofs_skip_write_bhops) {
@@ -401,23 +407,25 @@ int erofs_bflush(struct erofs_buffer_block *bb)
                                           padding, true);
 
                if (p->type != DATA)
-                       erofs_metablkcnt += BLK_ROUND_UP(sbi, p->buffers.off);
+                       sbi->bmngr->erofs_metablkcnt += BLK_ROUND_UP(sbi,
+                                                               p->buffers.off);
                erofs_dbg("block %u to %u flushed", p->blkaddr, blkaddr - 1);
-               erofs_bfree(p);
+               erofs_bfree(sbi, p);
        }
        return 0;
 }
 
-void erofs_bdrop(struct erofs_buffer_head *bh, bool tryrevoke)
+void erofs_bdrop(struct erofs_sb_info *sbi, struct erofs_buffer_head *bh,
+                bool tryrevoke)
 {
        struct erofs_buffer_block *const bb = bh->block;
        const erofs_blk_t blkaddr = bh->block->blkaddr;
        bool rollback = false;
-       struct erofs_sb_info *sbi = &g_sbi;
 
        /* tail_blkaddr could be rolled back after revoking all bhs */
        if (tryrevoke && blkaddr != NULL_ADDR &&
-           tail_blkaddr == blkaddr + BLK_ROUND_UP(sbi, bb->buffers.off))
+           sbi->bmngr->tail_blkaddr == blkaddr + BLK_ROUND_UP(sbi,
+                                                       bb->buffers.off))
                rollback = true;
 
        bh->op = &erofs_drop_directly_bhops;
@@ -427,13 +435,21 @@ void erofs_bdrop(struct erofs_buffer_head *bh, bool 
tryrevoke)
                return;
 
        if (!rollback && bb->type != DATA)
-               erofs_metablkcnt += BLK_ROUND_UP(sbi, bb->buffers.off);
-       erofs_bfree(bb);
+               sbi->bmngr->erofs_metablkcnt += BLK_ROUND_UP(sbi, 
bb->buffers.off);
+       erofs_bfree(sbi, bb);
        if (rollback)
-               tail_blkaddr = blkaddr;
+               sbi->bmngr->tail_blkaddr = blkaddr;
 }
 
-erofs_blk_t erofs_total_metablocks(void)
+erofs_blk_t erofs_total_metablocks(struct erofs_sb_info *sbi)
 {
-       return erofs_metablkcnt;
+       return sbi->bmngr->erofs_metablkcnt;
 }
+
+void erofs_buffer_exit(struct erofs_sb_info *sbi)
+{
+       if (sbi->bmngr) {
+               free(sbi->bmngr);
+               sbi->bmngr= NULL;
+       }
+}
\ No newline at end of file
diff --git a/lib/compress.c b/lib/compress.c
index b473587..e74e58c 100644
--- a/lib/compress.c
+++ b/lib/compress.c
@@ -1111,7 +1111,7 @@ int erofs_commit_compressed_file(struct 
z_erofs_compress_ictx *ictx,
        }
 
        if (compressed_blocks) {
-               ret = erofs_bh_balloon(bh, erofs_pos(sbi, compressed_blocks));
+               ret = erofs_bh_balloon(sbi, bh, erofs_pos(sbi, 
compressed_blocks));
                DBG_BUGON(ret != erofs_blksiz(sbi));
        } else {
                if (!cfg.c_fragments && !cfg.c_dedupe)
@@ -1126,7 +1126,7 @@ int erofs_commit_compressed_file(struct 
z_erofs_compress_ictx *ictx,
                bh->op = &erofs_skip_write_bhops;
                inode->bh_data = bh;
        } else {
-               erofs_bdrop(bh, false);
+               erofs_bdrop(sbi, bh, false);
        }
 
        inode->u.i_blocks = compressed_blocks;
@@ -1148,7 +1148,7 @@ err_free_meta:
        free(compressmeta);
        inode->compressmeta = NULL;
 err_free_idata:
-       erofs_bdrop(bh, true);  /* revoke buffer */
+       erofs_bdrop(sbi, bh, true);     /* revoke buffer */
        if (inode->idata) {
                free(inode->idata);
                inode->idata = NULL;
@@ -1366,14 +1366,14 @@ int erofs_mt_write_compressed_file(struct 
z_erofs_compress_ictx *ictx)
                pthread_cond_wait(&ictx->cond, &ictx->mutex);
        pthread_mutex_unlock(&ictx->mutex);
 
-       bh = erofs_balloc(DATA, 0, 0, 0);
+       bh = erofs_balloc(ictx->inode->sbi, DATA, 0, 0, 0);
        if (IS_ERR(bh)) {
                ret = PTR_ERR(bh);
                goto out;
        }
 
        DBG_BUGON(!head);
-       blkaddr = erofs_mapbh(bh->block);
+       blkaddr = erofs_mapbh(ictx->inode->sbi, bh->block);
 
        ret = 0;
        do {
@@ -1531,12 +1531,12 @@ int erofs_write_compressed_file(struct 
z_erofs_compress_ictx *ictx)
 #endif
 
        /* allocate main data buffer */
-       bh = erofs_balloc(DATA, 0, 0, 0);
+       bh = erofs_balloc(inode->sbi, DATA, 0, 0, 0);
        if (IS_ERR(bh)) {
                ret = PTR_ERR(bh);
                goto err_free_idata;
        }
-       blkaddr = erofs_mapbh(bh->block); /* start_blkaddr */
+       blkaddr = erofs_mapbh(inode->sbi, bh->block); /* start_blkaddr */
 
        ictx->seg_num = 1;
        sctx = (struct z_erofs_compress_sctx) {
@@ -1560,7 +1560,7 @@ int erofs_write_compressed_file(struct 
z_erofs_compress_ictx *ictx)
        goto out;
 
 err_free_idata:
-       erofs_bdrop(bh, true);  /* revoke buffer */
+       erofs_bdrop(inode->sbi, bh, true);      /* revoke buffer */
        if (inode->idata) {
                free(inode->idata);
                inode->idata = NULL;
@@ -1596,13 +1596,13 @@ static int z_erofs_build_compr_cfgs(struct 
erofs_sb_info *sbi,
                        }
                };
 
-               bh = erofs_battach(bh, META, sizeof(lz4alg));
+               bh = erofs_battach(sbi, bh, META, sizeof(lz4alg));
                if (IS_ERR(bh)) {
                        DBG_BUGON(1);
                        return PTR_ERR(bh);
                }
-               erofs_mapbh(bh->block);
-               ret = erofs_dev_write(sbi, &lz4alg, erofs_btell(bh, false),
+               erofs_mapbh(sbi, bh->block);
+               ret = erofs_dev_write(sbi, &lz4alg, erofs_btell(sbi, bh, false),
                                      sizeof(lz4alg));
                bh->op = &erofs_drop_directly_bhops;
        }
@@ -1620,13 +1620,13 @@ static int z_erofs_build_compr_cfgs(struct 
erofs_sb_info *sbi,
                        }
                };
 
-               bh = erofs_battach(bh, META, sizeof(lzmaalg));
+               bh = erofs_battach(sbi, bh, META, sizeof(lzmaalg));
                if (IS_ERR(bh)) {
                        DBG_BUGON(1);
                        return PTR_ERR(bh);
                }
-               erofs_mapbh(bh->block);
-               ret = erofs_dev_write(sbi, &lzmaalg, erofs_btell(bh, false),
+               erofs_mapbh(sbi, bh->block);
+               ret = erofs_dev_write(sbi, &lzmaalg, erofs_btell(sbi, bh, 
false),
                                      sizeof(lzmaalg));
                bh->op = &erofs_drop_directly_bhops;
        }
@@ -1644,13 +1644,13 @@ static int z_erofs_build_compr_cfgs(struct 
erofs_sb_info *sbi,
                        }
                };
 
-               bh = erofs_battach(bh, META, sizeof(zalg));
+               bh = erofs_battach(sbi, bh, META, sizeof(zalg));
                if (IS_ERR(bh)) {
                        DBG_BUGON(1);
                        return PTR_ERR(bh);
                }
-               erofs_mapbh(bh->block);
-               ret = erofs_dev_write(sbi, &zalg, erofs_btell(bh, false),
+               erofs_mapbh(sbi, bh->block);
+               ret = erofs_dev_write(sbi, &zalg, erofs_btell(sbi, bh, false),
                                      sizeof(zalg));
                bh->op = &erofs_drop_directly_bhops;
        }
@@ -1667,13 +1667,13 @@ static int z_erofs_build_compr_cfgs(struct 
erofs_sb_info *sbi,
                        }
                };
 
-               bh = erofs_battach(bh, META, sizeof(zalg));
+               bh = erofs_battach(sbi, bh, META, sizeof(zalg));
                if (IS_ERR(bh)) {
                        DBG_BUGON(1);
                        return PTR_ERR(bh);
                }
-               erofs_mapbh(bh->block);
-               ret = erofs_dev_write(sbi, &zalg, erofs_btell(bh, false),
+               erofs_mapbh(sbi, bh->block);
+               ret = erofs_dev_write(sbi, &zalg, erofs_btell(sbi, bh, false),
                                      sizeof(zalg));
                bh->op = &erofs_drop_directly_bhops;
        }
diff --git a/lib/inode.c b/lib/inode.c
index 8d60088..2ca91ff 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -186,7 +186,8 @@ static int __allocate_inode_bh_data(struct erofs_inode 
*inode,
        }
 
        /* allocate main data buffer */
-       bh = erofs_balloc(type, erofs_pos(inode->sbi, nblocks), 0, 0);
+       bh = erofs_balloc(inode->sbi, type, erofs_pos(inode->sbi, nblocks),
+                                                                       0, 0);
        if (IS_ERR(bh))
                return PTR_ERR(bh);
 
@@ -194,7 +195,7 @@ static int __allocate_inode_bh_data(struct erofs_inode 
*inode,
        inode->bh_data = bh;
 
        /* get blkaddr of the bh */
-       ret = erofs_mapbh(bh->block);
+       ret = erofs_mapbh(inode->sbi, bh->block);
        DBG_BUGON(ret < 0);
 
        /* write blocks except for the tail-end block */
@@ -314,8 +315,8 @@ erofs_nid_t erofs_lookupnid(struct erofs_inode *inode)
        erofs_off_t off, meta_offset;
 
        if (bh && (long long)inode->nid <= 0) {
-               erofs_mapbh(bh->block);
-               off = erofs_btell(bh, false);
+               erofs_mapbh(sbi, bh->block);
+               off = erofs_btell(sbi, bh, false);
 
                meta_offset = erofs_pos(sbi, sbi->meta_blkaddr);
                DBG_BUGON(off < meta_offset);
@@ -576,7 +577,7 @@ int erofs_iflush(struct erofs_inode *inode)
        int ret;
 
        if (inode->bh)
-               off = erofs_btell(inode->bh, false);
+               off = erofs_btell(sbi, inode->bh, false);
        else
                off = erofs_iloc(inode);
 
@@ -724,7 +725,7 @@ static int erofs_prepare_tail_block(struct erofs_inode 
*inode)
        bh = inode->bh_data;
        if (bh) {
                /* expend a block as the tail block (should be successful) */
-               ret = erofs_bh_balloon(bh, erofs_blksiz(sbi));
+               ret = erofs_bh_balloon(sbi, bh, erofs_blksiz(sbi));
                if (ret != erofs_blksiz(sbi)) {
                        DBG_BUGON(1);
                        return -EIO;
@@ -768,7 +769,7 @@ static int erofs_prepare_inode_buffer(struct erofs_inode 
*inode)
                        inode->datalayout = EROFS_INODE_FLAT_PLAIN;
        }
 
-       bh = erofs_balloc(INODE, inodesize, 0, inode->idata_size);
+       bh = erofs_balloc(inode->sbi, INODE, inodesize, 0, inode->idata_size);
        if (bh == ERR_PTR(-ENOSPC)) {
                int ret;
 
@@ -781,7 +782,7 @@ noinline:
                ret = erofs_prepare_tail_block(inode);
                if (ret)
                        return ret;
-               bh = erofs_balloc(INODE, inodesize, 0, 0);
+               bh = erofs_balloc(inode->sbi, INODE, inodesize, 0, 0);
                if (IS_ERR(bh))
                        return PTR_ERR(bh);
                DBG_BUGON(inode->bh_inline);
@@ -801,7 +802,7 @@ noinline:
                }
 
                /* allocate inline buffer */
-               ibh = erofs_battach(bh, META, inode->idata_size);
+               ibh = erofs_battach(inode->sbi, bh, META, inode->idata_size);
                if (IS_ERR(ibh))
                        return PTR_ERR(ibh);
 
@@ -818,7 +819,7 @@ noinline:
 static int erofs_bh_flush_write_inline(struct erofs_buffer_head *bh)
 {
        struct erofs_inode *const inode = bh->fsprivate;
-       const erofs_off_t off = erofs_btell(bh, false);
+       const erofs_off_t off = erofs_btell(inode->sbi, bh, false);
        int ret;
 
        ret = erofs_dev_write(inode->sbi, inode->idata, off, inode->idata_size);
@@ -860,29 +861,29 @@ static int erofs_write_tail_end(struct erofs_inode *inode)
                erofs_off_t pos, zero_pos;
 
                if (!bh) {
-                       bh = erofs_balloc(DATA, erofs_blksiz(sbi), 0, 0);
+                       bh = erofs_balloc(sbi, DATA, erofs_blksiz(sbi), 0, 0);
                        if (IS_ERR(bh))
                                return PTR_ERR(bh);
                        bh->op = &erofs_skip_write_bhops;
 
                        /* get blkaddr of bh */
-                       ret = erofs_mapbh(bh->block);
+                       ret = erofs_mapbh(sbi, bh->block);
                        inode->u.i_blkaddr = bh->block->blkaddr;
                        inode->bh_data = bh;
                } else {
                        if (inode->lazy_tailblock) {
                                /* expend a tail block (should be successful) */
-                               ret = erofs_bh_balloon(bh, erofs_blksiz(sbi));
+                               ret = erofs_bh_balloon(sbi, bh, 
erofs_blksiz(sbi));
                                if (ret != erofs_blksiz(sbi)) {
                                        DBG_BUGON(1);
                                        return -EIO;
                                }
                                inode->lazy_tailblock = false;
                        }
-                       ret = erofs_mapbh(bh->block);
+                       ret = erofs_mapbh(sbi, bh->block);
                }
                DBG_BUGON(ret < 0);
-               pos = erofs_btell(bh, true) - erofs_blksiz(sbi);
+               pos = erofs_btell(sbi, bh, true) - erofs_blksiz(sbi);
 
                /* 0'ed data should be padded at head for 0padding conversion */
                if (erofs_sb_has_lz4_0padding(sbi) && inode->compressed_idata) {
@@ -917,7 +918,7 @@ out:
                 * Don't leave DATA buffers which were written in the global
                 * buffer list. It will make balloc() slowly.
                 */
-               erofs_bdrop(bh, false);
+               erofs_bdrop(sbi, bh, false);
                inode->bh_data = NULL;
        }
        return 0;
@@ -1157,8 +1158,8 @@ static void erofs_fixup_meta_blkaddr(struct erofs_inode 
*rootdir)
        struct erofs_sb_info *sbi = rootdir->sbi;
        erofs_off_t off, meta_offset;
 
-       erofs_mapbh(bh->block);
-       off = erofs_btell(bh, false);
+       erofs_mapbh(sbi, bh->block);
+       off = erofs_btell(sbi, bh, false);
 
        if (off > rootnid_maxoffset)
                meta_offset = round_up(off - rootnid_maxoffset, 
erofs_blksiz(sbi));
@@ -1176,16 +1177,16 @@ static int erofs_inode_reserve_data_blocks(struct 
erofs_inode *inode)
        struct erofs_buffer_head *bh;
 
        /* allocate data blocks */
-       bh = erofs_balloc(DATA, alignedsz, 0, 0);
+       bh = erofs_balloc(sbi, DATA, alignedsz, 0, 0);
        if (IS_ERR(bh))
                return PTR_ERR(bh);
 
        /* get blkaddr of the bh */
-       (void)erofs_mapbh(bh->block);
+       (void)erofs_mapbh(sbi, bh->block);
 
        /* write blocks except for the tail-end block */
        inode->u.i_blkaddr = bh->block->blkaddr;
-       erofs_bdrop(bh, false);
+       erofs_bdrop(sbi, bh, false);
 
        inode->datalayout = EROFS_INODE_FLAT_PLAIN;
        tarerofs_blocklist_write(inode->u.i_blkaddr, nblocks, inode->i_ino[1]);
diff --git a/lib/super.c b/lib/super.c
index 3fbaf66..56eec37 100644
--- a/lib/super.c
+++ b/lib/super.c
@@ -149,6 +149,7 @@ void erofs_put_super(struct erofs_sb_info *sbi)
                sbi->devs = NULL;
        }
        erofs_xattr_prefixes_cleanup(sbi);
+       erofs_buffer_exit(sbi);
 }
 
 int erofs_writesb(struct erofs_sb_info *sbi, struct erofs_buffer_head *sb_bh,
@@ -176,7 +177,7 @@ int erofs_writesb(struct erofs_sb_info *sbi, struct 
erofs_buffer_head *sb_bh,
        char *buf;
        int ret;
 
-       *blocks         = erofs_mapbh(NULL);
+       *blocks         = erofs_mapbh(sbi, NULL);
        sb.blocks       = cpu_to_le32(*blocks);
        memcpy(sb.uuid, sbi->uuid, sizeof(sb.uuid));
        memcpy(sb.volume_name, sbi->volume_name, sizeof(sb.volume_name));
@@ -194,42 +195,42 @@ int erofs_writesb(struct erofs_sb_info *sbi, struct 
erofs_buffer_head *sb_bh,
        }
        memcpy(buf + EROFS_SUPER_OFFSET, &sb, sizeof(sb));
 
-       ret = erofs_dev_write(sbi, buf, sb_bh ? erofs_btell(sb_bh, false) : 0,
+       ret = erofs_dev_write(sbi, buf, sb_bh ? erofs_btell(sbi, sb_bh, false) 
: 0,
                              EROFS_SUPER_END);
        free(buf);
        if (sb_bh)
-               erofs_bdrop(sb_bh, false);
+               erofs_bdrop(sbi, sb_bh, false);
        return ret;
 }
 
-struct erofs_buffer_head *erofs_reserve_sb(void)
+struct erofs_buffer_head *erofs_reserve_sb(struct erofs_sb_info *sbi)
 {
        struct erofs_buffer_head *bh;
        int err;
 
-       erofs_buffer_init(0);
-       bh = erofs_balloc(META, 0, 0, 0);
+       erofs_buffer_init(sbi, 0);
+       bh = erofs_balloc(sbi, META, 0, 0, 0);
        if (IS_ERR(bh)) {
                erofs_err("failed to allocate super: %s", PTR_ERR(bh));
                return bh;
        }
        bh->op = &erofs_skip_write_bhops;
-       err = erofs_bh_balloon(bh, EROFS_SUPER_END);
+       err = erofs_bh_balloon(sbi, bh, EROFS_SUPER_END);
        if (err < 0) {
                erofs_err("failed to balloon super: %s", erofs_strerror(err));
                goto err_bdrop;
        }
 
        /* make sure that the super block should be the very first blocks */
-       (void)erofs_mapbh(bh->block);
-       if (erofs_btell(bh, false) != 0) {
+       (void)erofs_mapbh(sbi, bh->block);
+       if (erofs_btell(sbi, bh, false) != 0) {
                erofs_err("failed to pin super block @ 0");
                err = -EFAULT;
                goto err_bdrop;
        }
        return bh;
 err_bdrop:
-       erofs_bdrop(bh, true);
+       erofs_bdrop(sbi, bh, true);
        return ERR_PTR(err);
 }
 
diff --git a/lib/xattr.c b/lib/xattr.c
index b0f80e9..3356c3e 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -906,7 +906,7 @@ int erofs_build_shared_xattrs_from_path(struct 
erofs_sb_info *sbi, const char *p
                return -ENOMEM;
        }
 
-       bh = erofs_balloc(XATTR, shared_xattrs_size, 0, 0);
+       bh = erofs_balloc(sbi, XATTR, shared_xattrs_size, 0, 0);
        if (IS_ERR(bh)) {
                free(sorted_n);
                free(buf);
@@ -914,8 +914,8 @@ int erofs_build_shared_xattrs_from_path(struct 
erofs_sb_info *sbi, const char *p
        }
        bh->op = &erofs_skip_write_bhops;
 
-       erofs_mapbh(bh->block);
-       off = erofs_btell(bh, false);
+       erofs_mapbh(sbi, bh->block);
+       off = erofs_btell(sbi, bh, false);
 
        sbi->xattr_blkaddr = off / erofs_blksiz(sbi);
        off %= erofs_blksiz(sbi);
@@ -930,9 +930,9 @@ int erofs_build_shared_xattrs_from_path(struct 
erofs_sb_info *sbi, const char *p
        shared_xattrs_list = sorted_n[0];
        free(sorted_n);
        bh->op = &erofs_drop_directly_bhops;
-       ret = erofs_dev_write(sbi, buf, erofs_btell(bh, false), 
shared_xattrs_size);
+       ret = erofs_dev_write(sbi, buf, erofs_btell(sbi, bh, false), 
shared_xattrs_size);
        free(buf);
-       erofs_bdrop(bh, false);
+       erofs_bdrop(sbi, bh, false);
 out:
        erofs_cleanxattrs(true);
        return ret;
diff --git a/mkfs/main.c b/mkfs/main.c
index 37f250b..1793fd8 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -1105,7 +1105,7 @@ static int erofs_mkfs_rebuild_load_trees(struct 
erofs_inode *root)
        return 0;
 }
 
-static void erofs_mkfs_showsummaries(erofs_blk_t nblocks)
+static void erofs_mkfs_showsummaries(struct erofs_sb_info *sbi, erofs_blk_t 
nblocks)
 {
        char uuid_str[37] = {};
        char *incr = incremental_mode ? "new" : "total";
@@ -1121,7 +1121,7 @@ static void erofs_mkfs_showsummaries(erofs_blk_t nblocks)
                "Filesystem %s metadata blocks: %u\n"
                "Filesystem %s deduplicated bytes (of source files): %llu\n",
                uuid_str, nblocks, 1U << g_sbi.blkszbits, g_sbi.inos | 0ULL,
-               incr, erofs_total_metablocks(),
+               incr, erofs_total_metablocks(sbi),
                incr, g_sbi.saved_by_deduplication | 0ULL);
 }
 
@@ -1245,7 +1245,7 @@ int main(int argc, char **argv)
        }
 
        if (!incremental_mode) {
-               sb_bh = erofs_reserve_sb();
+               sb_bh = erofs_reserve_sb(&g_sbi);
                if (IS_ERR(sb_bh)) {
                        err = PTR_ERR(sb_bh);
                        goto exit;
@@ -1270,7 +1270,7 @@ int main(int argc, char **argv)
                        u.startblk = DIV_ROUND_UP(u.st.st_size, 
erofs_blksiz(&g_sbi));
                else
                        u.startblk = g_sbi.primarydevice_blocks;
-               erofs_buffer_init(u.startblk);
+               erofs_buffer_init(&g_sbi, u.startblk);
                sb_bh = NULL;
        }
 
@@ -1392,7 +1392,7 @@ int main(int argc, char **argv)
        }
 
        /* flush all buffers except for the superblock */
-       err = erofs_bflush(NULL);
+       err = erofs_bflush(&g_sbi, NULL);
        if (err)
                goto exit;
 
@@ -1405,7 +1405,7 @@ int main(int argc, char **argv)
                goto exit;
 
        /* flush all remaining buffers */
-       err = erofs_bflush(NULL);
+       err = erofs_bflush(&g_sbi, NULL);
        if (err)
                goto exit;
 
@@ -1448,6 +1448,7 @@ exit:
                return 1;
        }
        erofs_update_progressinfo("Build completed.\n");
-       erofs_mkfs_showsummaries(nblocks);
+       erofs_mkfs_showsummaries(&g_sbi, nblocks);
+       erofs_put_super(&g_sbi);
        return 0;
 }
-- 
2.43.5


Reply via email to