[PATCH v2 3/4] erofs: support buffer block reservation
Gao Xiang
hsiangkao at linux.alibaba.com
Thu Dec 19 17:43:30 AEDT 2024
In order to support data alignment, add support for recording multiple
block reservations.
Signed-off-by: Gao Xiang <hsiangkao at 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
More information about the Linux-erofs
mailing list