aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGao Xiang <hsiangkao@linux.alibaba.com>2023-03-28 11:54:55 +0800
committerGao Xiang <hsiangkao@linux.alibaba.com>2023-03-28 11:59:13 +0800
commitb98311055be723af3bf16f96b6241497363ccdf7 (patch)
tree25de85195fea118b27c0f8401f45a1d5655db68f
parentf09c4fa35959771e2e595657fb9fa03251b4d023 (diff)
downloaderofs-utils-b98311055be723af3bf16f96b6241497363ccdf7.tar.gz
erofs-utils: fix missing tail blocks for directories
Currently directory blocks will be allocated after inode metadata space is reserved, but miss to fix tail blocks. Fixes: 21d84349e79a ("erofs-utils: rearrange on-disk metadata") Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com> Link: https://lore.kernel.org/r/20230328035456.89831-1-hsiangkao@linux.alibaba.com
-rw-r--r--include/erofs/internal.h1
-rw-r--r--lib/inode.c16
2 files changed, 16 insertions, 1 deletions
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 1f1e730..641a795 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -180,6 +180,7 @@ struct erofs_inode {
/* inline tail-end packing size */
unsigned short idata_size;
bool compressed_idata;
+ bool lazy_tailblock;
unsigned int xattr_isize;
unsigned int extent_isize;
diff --git a/lib/inode.c b/lib/inode.c
index 9db84a8..871968d 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -608,7 +608,12 @@ static int erofs_prepare_tail_block(struct erofs_inode *inode)
if (bh) {
/* expend a block as the tail block (should be successful) */
ret = erofs_bh_balloon(bh, erofs_blksiz());
- DBG_BUGON(ret != erofs_blksiz());
+ if (ret != erofs_blksiz()) {
+ DBG_BUGON(1);
+ return -EIO;
+ }
+ } else {
+ inode->lazy_tailblock = true;
}
return 0;
}
@@ -743,6 +748,15 @@ static int erofs_write_tail_end(struct erofs_inode *inode)
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());
+ if (ret != erofs_blksiz()) {
+ DBG_BUGON(1);
+ return -EIO;
+ }
+ inode->lazy_tailblock = false;
+ }
ret = erofs_mapbh(bh->block);
}
DBG_BUGON(ret < 0);