In order to support data alignment, add support for recording multiple
block reservations.

Signed-off-by: Gao Xiang <hsiang...@linux.alibaba.com>
---
 include/erofs/cache.h | 11 +++++++----
 lib/cache.c           | 32 ++++++++++++++++----------------
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/include/erofs/cache.h b/include/erofs/cache.h
index 646d6de..d8559a8 100644
--- a/include/erofs/cache.h
+++ b/include/erofs/cache.h
@@ -35,11 +35,14 @@ struct erofs_bhops {
 
 struct erofs_buffer_head {
        struct list_head list;
-       struct erofs_buffer_block *block;
-
+       union {
+               struct {
+                       struct erofs_buffer_block *block;
+                       const struct erofs_bhops *op;
+               };
+               erofs_blk_t nblocks;
+       };
        erofs_off_t off;
-       const struct erofs_bhops *op;
-
        void *fsprivate;
 };
 
diff --git a/lib/cache.c b/lib/cache.c
index 1cc5007..cb05466 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -74,8 +74,7 @@ static int __erofs_battach(struct erofs_buffer_block *bb,
 {
        struct erofs_bufmgr *bmgr = bb->buffers.fsprivate;
        struct erofs_sb_info *sbi = bmgr->sbi;
-       const unsigned int blksiz = erofs_blksiz(sbi);
-       const unsigned int blkmask = blksiz - 1;
+       const unsigned int blkmask = erofs_blksiz(sbi) - 1;
        erofs_off_t boff = bb->buffers.off;
        const erofs_off_t alignedoffset = roundup(boff, alignsize);
        bool tailupdate = false;
@@ -87,7 +86,8 @@ static int __erofs_battach(struct erofs_buffer_block *bb,
                        + inline_ext > blkmask)
                return -ENOSPC;
 
-       oob = cmpsgn((alignedoffset & blkmask) + incr + inline_ext, blksiz);
+       oob = cmpsgn(roundup(boff, alignsize) + incr + inline_ext,
+                    bb->buffers.nblocks << sbi->blkszbits);
        if (oob >= 0) {
                /* the next buffer block should be NULL_ADDR all the time */
                if (oob && list_next_entry(bb, list)->blkaddr != NULL_ADDR)
@@ -96,7 +96,7 @@ static int __erofs_battach(struct erofs_buffer_block *bb,
                blkaddr = bb->blkaddr;
                if (blkaddr != NULL_ADDR) {
                        tailupdate = (bmgr->tail_blkaddr == blkaddr +
-                                     BLK_ROUND_UP(sbi, boff));
+                                     bb->buffers.nblocks);
                        if (oob && !tailupdate)
                                return -EINVAL;
                }
@@ -110,10 +110,11 @@ static int __erofs_battach(struct erofs_buffer_block *bb,
                }
                boff = alignedoffset + incr;
                bb->buffers.off = boff;
+               bb->buffers.nblocks = max_t(erofs_blk_t, bb->buffers.nblocks,
+                                           BLK_ROUND_UP(sbi, boff));
                /* need to update the tail_blkaddr */
                if (tailupdate)
-                       bmgr->tail_blkaddr = blkaddr +
-                                               BLK_ROUND_UP(sbi, boff);
+                       bmgr->tail_blkaddr = blkaddr + bb->buffers.nblocks;
                erofs_bupdate_mapped(bb);
        }
        return ((alignedoffset + incr + blkmask) & blkmask) + 1;
@@ -266,6 +267,7 @@ struct erofs_buffer_head *erofs_balloc(struct erofs_bufmgr 
*bmgr,
                bb->type = type;
                bb->blkaddr = NULL_ADDR;
                bb->buffers.off = 0;
+               bb->buffers.nblocks = 0;
                bb->buffers.fsprivate = bmgr;
                init_list_head(&bb->buffers.list);
                if (type == DATA)
@@ -319,7 +321,7 @@ 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 void __erofs_mapbh(struct erofs_buffer_block *bb)
 {
        struct erofs_bufmgr *bmgr = bb->buffers.fsprivate;
        erofs_blk_t blkaddr;
@@ -330,10 +332,9 @@ static erofs_blk_t __erofs_mapbh(struct erofs_buffer_block 
*bb)
                erofs_bupdate_mapped(bb);
        }
 
-       blkaddr = bb->blkaddr + BLK_ROUND_UP(bmgr->sbi, bb->buffers.off);
+       blkaddr = bb->blkaddr + bb->buffers.nblocks;
        if (blkaddr > bmgr->tail_blkaddr)
                bmgr->tail_blkaddr = blkaddr;
-       return blkaddr;
 }
 
 erofs_blk_t erofs_mapbh(struct erofs_bufmgr *bmgr,
@@ -353,7 +354,7 @@ erofs_blk_t erofs_mapbh(struct erofs_bufmgr *bmgr,
                        break;
 
                DBG_BUGON(t->blkaddr != NULL_ADDR);
-               (void)__erofs_mapbh(t);
+               __erofs_mapbh(t);
        } while (t != bb);
        return bmgr->tail_blkaddr;
 }
@@ -389,7 +390,8 @@ int erofs_bflush(struct erofs_bufmgr *bmgr,
                if (p == bb)
                        break;
 
-               blkaddr = __erofs_mapbh(p);
+               __erofs_mapbh(p);
+               blkaddr = p->blkaddr + BLK_ROUND_UP(sbi, p->buffers.off);
 
                list_for_each_entry_safe(bh, nbh, &p->buffers.list, list) {
                        if (bh->op == &erofs_skip_write_bhops) {
@@ -412,8 +414,7 @@ int erofs_bflush(struct erofs_bufmgr *bmgr,
                                           padding, true);
 
                if (p->type != DATA)
-                       bmgr->metablkcnt +=
-                               BLK_ROUND_UP(sbi, p->buffers.off);
+                       bmgr->metablkcnt += p->buffers.nblocks;
                erofs_dbg("block %u to %u flushed", p->blkaddr, blkaddr - 1);
                erofs_bfree(p);
        }
@@ -424,13 +425,12 @@ void erofs_bdrop(struct erofs_buffer_head *bh, bool 
tryrevoke)
 {
        struct erofs_buffer_block *const bb = bh->block;
        struct erofs_bufmgr *bmgr = bb->buffers.fsprivate;
-       struct erofs_sb_info *sbi = bmgr->sbi;
        const erofs_blk_t blkaddr = bh->block->blkaddr;
        bool rollback = false;
 
        /* tail_blkaddr could be rolled back after revoking all bhs */
        if (tryrevoke && blkaddr != NULL_ADDR &&
-           bmgr->tail_blkaddr == blkaddr + BLK_ROUND_UP(sbi, bb->buffers.off))
+           bmgr->tail_blkaddr == blkaddr + bb->buffers.nblocks)
                rollback = true;
 
        bh->op = &erofs_drop_directly_bhops;
@@ -440,7 +440,7 @@ void erofs_bdrop(struct erofs_buffer_head *bh, bool 
tryrevoke)
                return;
 
        if (!rollback && bb->type != DATA)
-               bmgr->metablkcnt += BLK_ROUND_UP(sbi, bb->buffers.off);
+               bmgr->metablkcnt += bb->buffers.nblocks;
        erofs_bfree(bb);
        if (rollback)
                bmgr->tail_blkaddr = blkaddr;
-- 
2.43.5

Reply via email to