[PATCH v2 3/4] erofs-utils: lib: delay erofs_prepare_xattr_ibody()

Gao Xiang hsiangkao at linux.alibaba.com
Tue Dec 30 05:06:45 AEDT 2025


Call erofs_prepare_xattr_ibody() in erofs_mkfs_handle_nondirectory()
and erofs_mkfs_create_directory() instead.

Note that it shouldn't be called in erofs_prepare_inode_buffer(),
which is too late.

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 lib/inode.c | 77 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 44 insertions(+), 33 deletions(-)

diff --git a/lib/inode.c b/lib/inode.c
index dc3d82749405..7ee16f4db183 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -1459,7 +1459,12 @@ static int erofs_mkfs_handle_nondirectory(const struct erofs_mkfs_btctx *btctx,
 					  struct erofs_mkfs_job_ndir_ctx *ctx)
 {
 	struct erofs_inode *inode = ctx->inode;
-	int ret = 0;
+	int ret;
+
+	ret = erofs_prepare_xattr_ibody(inode,
+					btctx->incremental && IS_ROOT(inode));
+	if (ret < 0)
+		return ret;
 
 	if (S_ISLNK(inode->i_mode)) {
 		char *symlink = inode->i_link;
@@ -1490,6 +1495,42 @@ static int erofs_mkfs_handle_nondirectory(const struct erofs_mkfs_btctx *btctx,
 	return 0;
 }
 
+static int erofs_mkfs_create_directory(const struct erofs_mkfs_btctx *ctx,
+				       struct erofs_inode *inode)
+{
+	unsigned int bsz = erofs_blksiz(inode->sbi);
+	int ret;
+
+	ret = erofs_prepare_xattr_ibody(inode, ctx->incremental && IS_ROOT(inode));
+	if (ret < 0)
+		return ret;
+
+	if (inode->datalayout == EROFS_INODE_DATALAYOUT_MAX) {
+		inode->datalayout = EROFS_INODE_FLAT_INLINE;
+
+		ret = erofs_begin_compress_dir(ctx->im, inode);
+		if (ret && ret != -ENOSPC)
+			return ret;
+	} else {
+		DBG_BUGON(inode->datalayout != EROFS_INODE_FLAT_PLAIN);
+	}
+
+	/* it will be used in erofs_prepare_inode_buffer */
+	if (inode->datalayout == EROFS_INODE_FLAT_INLINE)
+		inode->idata_size = inode->i_size & (bsz - 1);
+
+	/*
+	 * Directory on-disk inodes should be close to other inodes
+	 * in the parent directory since parent directories should
+	 * generally be prioritized.
+	 */
+	ret = erofs_prepare_inode_buffer(ctx->im, inode);
+	if (ret)
+		return ret;
+	inode->bh->op = &erofs_skip_write_bhops;
+	return 0;
+}
+
 enum erofs_mkfs_jobtype {	/* ordered job types */
 	EROFS_MKFS_JOB_NDIR,
 	EROFS_MKFS_JOB_DIR,
@@ -1518,34 +1559,8 @@ static int erofs_mkfs_jobfn(const struct erofs_mkfs_btctx *ctx,
 	if (item->type == EROFS_MKFS_JOB_NDIR)
 		return erofs_mkfs_handle_nondirectory(ctx, &item->u.ndir);
 
-	if (item->type == EROFS_MKFS_JOB_DIR) {
-		unsigned int bsz = erofs_blksiz(inode->sbi);
-
-		if (inode->datalayout == EROFS_INODE_DATALAYOUT_MAX) {
-			inode->datalayout = EROFS_INODE_FLAT_INLINE;
-
-			ret = erofs_begin_compress_dir(ctx->im, inode);
-			if (ret && ret != -ENOSPC)
-				return ret;
-		} else {
-			DBG_BUGON(inode->datalayout != EROFS_INODE_FLAT_PLAIN);
-		}
-
-		/* it will be used in erofs_prepare_inode_buffer */
-		if (inode->datalayout == EROFS_INODE_FLAT_INLINE)
-			inode->idata_size = inode->i_size & (bsz - 1);
-
-		/*
-		 * Directory on-disk inodes should be close to other inodes
-		 * in the parent directory since parent directories should
-		 * generally be prioritized.
-		 */
-		ret = erofs_prepare_inode_buffer(ctx->im, inode);
-		if (ret)
-			return ret;
-		inode->bh->op = &erofs_skip_write_bhops;
-		return 0;
-	}
+	if (item->type == EROFS_MKFS_JOB_DIR)
+		return erofs_mkfs_create_directory(ctx, inode);
 
 	if (item->type == EROFS_MKFS_JOB_DIR_BH) {
 		ret = erofs_write_dir_file(inode);
@@ -1964,10 +1979,6 @@ static int erofs_mkfs_handle_inode(const struct erofs_mkfs_btctx *ctx,
 	else if (inode->whiteouts)
 		erofs_set_origin_xattr(inode);
 
-	ret = erofs_prepare_xattr_ibody(inode, ctx->incremental && IS_ROOT(inode));
-	if (ret < 0)
-		return ret;
-
 	if (!S_ISDIR(inode->i_mode)) {
 		ret = erofs_mkfs_begin_nondirectory(ctx, inode);
 	} else {
-- 
2.43.5



More information about the Linux-erofs mailing list