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 <[email protected]>
---
 include/erofs/internal.h |  1 +
 lib/inode.c              | 16 +++++++++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)

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);
-- 
2.24.4

Reply via email to