[PATCH v2] erofs-utils: separate directory data from file data

Gao Xiang hsiangkao at linux.alibaba.com
Fri Mar 24 19:27:49 AEDT 2023


It'd better to split directory data out although directory data is
still not lazy written since it tends to put directory data next to
the corresponding inode metadata.

Laterly, aligned directory data could be written in a batch way so
that inodes can be more compact.

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
v2: make sure the super block should be the first blocks due to
    the new allocation policy.
 include/erofs/cache.h |  9 +++++++--
 lib/inode.c           | 11 ++++++-----
 mkfs/main.c           |  7 +++++++
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/include/erofs/cache.h b/include/erofs/cache.h
index 1461305..b04eb47 100644
--- a/include/erofs/cache.h
+++ b/include/erofs/cache.h
@@ -22,10 +22,12 @@ struct erofs_buffer_block;
 #define META		1
 /* including inline xattrs, extent */
 #define INODE		2
+/* directory data */
+#define DIRA		3
 /* shared xattrs */
-#define XATTR		3
+#define XATTR		4
 /* device table */
-#define DEVT		4
+#define DEVT		5
 
 struct erofs_bhops {
 	bool (*preflush)(struct erofs_buffer_head *bh);
@@ -60,6 +62,9 @@ static inline const int get_alignsize(int type, int *type_ret)
 	if (type == INODE) {
 		*type_ret = META;
 		return sizeof(struct erofs_inode_compact);
+	} else if (type == DIRA) {
+		*type_ret = META;
+		return erofs_blksiz();
 	} else if (type == XATTR) {
 		*type_ret = META;
 		return sizeof(struct erofs_xattr_entry);
diff --git a/lib/inode.c b/lib/inode.c
index 7167f19..9db84a8 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -142,7 +142,8 @@ struct erofs_dentry *erofs_d_alloc(struct erofs_inode *parent,
 
 /* allocate main data for a inode */
 static int __allocate_inode_bh_data(struct erofs_inode *inode,
-				    unsigned long nblocks)
+				    unsigned long nblocks,
+				    int type)
 {
 	struct erofs_buffer_head *bh;
 	int ret;
@@ -154,7 +155,7 @@ static int __allocate_inode_bh_data(struct erofs_inode *inode,
 	}
 
 	/* allocate main data buffer */
-	bh = erofs_balloc(DATA, erofs_pos(nblocks), 0, 0);
+	bh = erofs_balloc(type, erofs_pos(nblocks), 0, 0);
 	if (IS_ERR(bh))
 		return PTR_ERR(bh);
 
@@ -305,7 +306,7 @@ static int erofs_write_dir_file(struct erofs_inode *dir)
 	q = used = blkno = 0;
 
 	/* allocate dir main data */
-	ret = __allocate_inode_bh_data(dir, erofs_blknr(dir->i_size));
+	ret = __allocate_inode_bh_data(dir, erofs_blknr(dir->i_size), DIRA);
 	if (ret)
 		return ret;
 
@@ -353,7 +354,7 @@ static int erofs_write_file_from_buffer(struct erofs_inode *inode, char *buf)
 
 	inode->datalayout = EROFS_INODE_FLAT_INLINE;
 
-	ret = __allocate_inode_bh_data(inode, nblocks);
+	ret = __allocate_inode_bh_data(inode, nblocks, DATA);
 	if (ret)
 		return ret;
 
@@ -386,7 +387,7 @@ static int write_uncompressed_file_from_fd(struct erofs_inode *inode, int fd)
 	inode->datalayout = EROFS_INODE_FLAT_INLINE;
 	nblocks = inode->i_size / erofs_blksiz();
 
-	ret = __allocate_inode_bh_data(inode, nblocks);
+	ret = __allocate_inode_bh_data(inode, nblocks, DATA);
 	if (ret)
 		return ret;
 
diff --git a/mkfs/main.c b/mkfs/main.c
index a05d4f9..27e3f03 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -802,6 +802,13 @@ int main(int argc, char **argv)
 		goto exit;
 	}
 
+	/* make sure that the super block should be the very first blocks */
+	(void)erofs_mapbh(sb_bh->block);
+	if (erofs_btell(sb_bh, false) != 0) {
+		erofs_err("failed to reserve erofs_super_block");
+		goto exit;
+	}
+
 	err = erofs_load_compress_hints();
 	if (err) {
 		erofs_err("failed to load compress hints %s",
-- 
2.24.4



More information about the Linux-erofs mailing list