[PATCH 2/3] erofs-utils: lib: consolidate erofs_iflush()

Gao Xiang hsiangkao at linux.alibaba.com
Thu Jul 17 02:24:40 AEST 2025


.. Avoid erofs_dev_write() and use the bdev virtual file instead.

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 include/erofs/internal.h |  3 +-
 lib/blobchunk.c          |  6 ++--
 lib/inode.c              | 67 +++++++++++++++++++---------------------
 lib/super.c              |  1 -
 4 files changed, 35 insertions(+), 42 deletions(-)

diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index b5df8a48..65d40840 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -95,7 +95,6 @@ struct erofs_sb_info {
 	u32 feature_compat;
 	u32 feature_incompat;
 
-	unsigned char islotbits;
 	unsigned char blkszbits;
 
 	u32 sb_size;			/* total superblock size */
@@ -293,7 +292,7 @@ static inline erofs_off_t erofs_iloc(struct erofs_inode *inode)
 	struct erofs_sb_info *sbi = inode->sbi;
 
 	return erofs_pos(sbi, sbi->meta_blkaddr) +
-			(inode->nid << sbi->islotbits);
+			(inode->nid << EROFS_ISLOTBITS);
 }
 
 static inline bool is_inode_layout_compression(struct erofs_inode *inode)
diff --git a/lib/blobchunk.c b/lib/blobchunk.c
index 3388ce0d..bbc69cfb 100644
--- a/lib/blobchunk.c
+++ b/lib/blobchunk.c
@@ -193,7 +193,6 @@ int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
 		else
 			memcpy(inode->chunkindexes + dst, &idx, sizeof(idx));
 	}
-	off = roundup(off, unit);
 	if (extent_start != EROFS_NULL_ADDR) {
 		extent_end = min(extent_end, extent_start + remaining_blks);
 		zeroedlen = inode->i_size & (erofs_blksiz(sbi) - 1);
@@ -202,8 +201,9 @@ int erofs_blob_write_chunk_indexes(struct erofs_inode *inode,
 		tarerofs_blocklist_write(extent_start, extent_end - extent_start,
 					 source_offset, zeroedlen);
 	}
-	return erofs_dev_write(inode->sbi, inode->chunkindexes, off,
-			       inode->extent_isize);
+	off = roundup(off, unit);
+	return erofs_io_pwrite(&sbi->bdev, inode->chunkindexes,
+			       off, inode->extent_isize);
 }
 
 int erofs_blob_mergechunks(struct erofs_inode *inode, unsigned int chunkbits,
diff --git a/lib/inode.c b/lib/inode.c
index 4f6715af..f7c6b87f 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -609,22 +609,23 @@ int erofs_write_unencoded_file(struct erofs_inode *inode, int fd, u64 fpos)
 
 int erofs_iflush(struct erofs_inode *inode)
 {
-	const u16 icount = EROFS_INODE_XATTR_ICOUNT(inode->xattr_isize);
+	u16 icount = EROFS_INODE_XATTR_ICOUNT(inode->xattr_isize);
 	struct erofs_sb_info *sbi = inode->sbi;
-	erofs_off_t off;
+	struct erofs_buffer_head *bh = inode->bh;
+	erofs_off_t off = erofs_iloc(inode);
 	union {
 		struct erofs_inode_compact dic;
 		struct erofs_inode_extended die;
 	} u = {};
 	union erofs_inode_i_u u1;
 	union erofs_inode_i_nb nb;
+	unsigned int iovcnt = 0;
+	struct iovec iov[2];
+	char *xattrs = NULL;
 	bool nlink_1 = true;
 	int ret, fmt;
 
-	if (inode->bh)
-		off = erofs_btell(inode->bh, false);
-	else
-		off = erofs_iloc(inode);
+	DBG_BUGON(bh && erofs_btell(bh, false) != off);
 
 	if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||
 	    S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode))
@@ -702,41 +703,41 @@ int erofs_iflush(struct erofs_inode *inode)
 	default:
 		erofs_err("unsupported on-disk inode version of nid %llu",
 			  (unsigned long long)inode->nid);
-		BUG_ON(1);
+		DBG_BUGON(1);
+		return -EOPNOTSUPP;
 	}
 
-	ret = erofs_dev_write(sbi, &u, off, inode->inode_isize);
-	if (ret)
-		return ret;
-	off += inode->inode_isize;
-
+	iov[iovcnt++] = (struct iovec){ .iov_base = &u,
+					.iov_len = inode->inode_isize };
 	if (inode->xattr_isize) {
-		char *xattrs = erofs_export_xattr_ibody(inode);
-
+		xattrs = erofs_export_xattr_ibody(inode);
 		if (IS_ERR(xattrs))
 			return PTR_ERR(xattrs);
-
-		ret = erofs_dev_write(sbi, xattrs, off, inode->xattr_isize);
-		free(xattrs);
-		if (ret)
-			return ret;
-
-		off += inode->xattr_isize;
+		iov[iovcnt++] = (struct iovec){ .iov_base = xattrs,
+						.iov_len = inode->xattr_isize };
 	}
 
+	ret = erofs_io_pwritev(&sbi->bdev, iov, iovcnt, off);
+	free(xattrs);
+	if (ret != inode->inode_isize + inode->xattr_isize)
+		return ret < 0 ? ret : -EIO;
+
+	off += ret;
 	if (inode->extent_isize) {
 		if (inode->datalayout == EROFS_INODE_CHUNK_BASED) {
 			ret = erofs_blob_write_chunk_indexes(inode, off);
-			if (ret)
-				return ret;
-		} else {
-			/* write compression metadata */
+		} else {	/* write compression metadata */
 			off = roundup(off, 8);
-			ret = erofs_dev_write(sbi, inode->compressmeta, off,
-					      inode->extent_isize);
-			if (ret)
-				return ret;
+			ret = erofs_io_pwrite(&sbi->bdev, inode->compressmeta,
+					      off, inode->extent_isize);
 		}
+		if (ret != inode->extent_isize)
+			return ret < 0 ? ret : -EIO;
+	}
+	if (bh) {
+		inode->bh = NULL;
+		erofs_iput(inode);
+		return erofs_bh_flush_generic_end(bh);
 	}
 	return 0;
 }
@@ -744,15 +745,9 @@ int erofs_iflush(struct erofs_inode *inode)
 static int erofs_bh_flush_write_inode(struct erofs_buffer_head *bh)
 {
 	struct erofs_inode *inode = bh->fsprivate;
-	int ret;
 
 	DBG_BUGON(inode->bh != bh);
-	ret = erofs_iflush(inode);
-	if (ret)
-		return ret;
-	inode->bh = NULL;
-	erofs_iput(inode);
-	return erofs_bh_flush_generic_end(bh);
+	return erofs_iflush(inode);
 }
 
 static struct erofs_bhops erofs_write_inode_bhops = {
diff --git a/lib/super.c b/lib/super.c
index 0533a7c8..e5364d27 100644
--- a/lib/super.c
+++ b/lib/super.c
@@ -114,7 +114,6 @@ int erofs_read_superblock(struct erofs_sb_info *sbi)
 	sbi->xattr_blkaddr = le32_to_cpu(dsb->xattr_blkaddr);
 	sbi->xattr_prefix_start = le32_to_cpu(dsb->xattr_prefix_start);
 	sbi->xattr_prefix_count = dsb->xattr_prefix_count;
-	sbi->islotbits = EROFS_ISLOTBITS;
 	if (erofs_sb_has_48bit(sbi) && dsb->rootnid_8b) {
 		sbi->root_nid = le64_to_cpu(dsb->rootnid_8b);
 		sbi->primarydevice_blocks = (sbi->primarydevice_blocks << 32) |
-- 
2.43.5



More information about the Linux-erofs mailing list