[PATCH] erofs: support ddtaridx format informally

Gao Xiang hsiangkao at linux.alibaba.com
Fri Jul 12 17:40:02 AEST 2024


`ddtaridx` is a customized tar meta-only format implemented in
Alibaba's OverlayBD project [1].

Please don't use it externally if you have no idea of this except for
the OverlayBD project.  It will be removed if some better way exists.

[1] https://github.com/containerd/overlaybd
Cc: Yifan Yuan <tuji.yyf at alibaba-inc.com>
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 include/erofs/tar.h |  1 +
 lib/tar.c           | 32 ++++++++++++--------------------
 2 files changed, 13 insertions(+), 20 deletions(-)

diff --git a/include/erofs/tar.h b/include/erofs/tar.h
index 403f3a8..6fa72eb 100644
--- a/include/erofs/tar.h
+++ b/include/erofs/tar.h
@@ -61,6 +61,7 @@ struct erofs_tarfile {
 	int fd;
 	u64 offset;
 	bool index_mode, headeronly_mode, rvsp_mode, aufs;
+	bool ddtaridx_mode;
 };
 
 void erofs_iostream_close(struct erofs_iostream *ios);
diff --git a/lib/tar.c b/lib/tar.c
index 5e2c5b8..142c42e 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -611,19 +611,6 @@ static int tarerofs_write_file_data(struct erofs_inode *inode,
 	return 0;
 }
 
-static int tarerofs_write_file_index(struct erofs_inode *inode,
-		struct erofs_tarfile *tar, erofs_off_t data_offset)
-{
-	int ret;
-
-	ret = tarerofs_write_chunkes(inode, data_offset);
-	if (ret)
-		return ret;
-	if (erofs_iostream_lskip(&tar->ios, inode->i_size))
-		return -EIO;
-	return 0;
-}
-
 int tarerofs_parse_tar(struct erofs_inode *root, struct erofs_tarfile *tar)
 {
 	char path[PATH_MAX];
@@ -631,7 +618,7 @@ int tarerofs_parse_tar(struct erofs_inode *root, struct erofs_tarfile *tar)
 	struct erofs_sb_info *sbi = root->sbi;
 	bool whout, opq, e = false;
 	struct stat st;
-	erofs_off_t tar_offset, data_offset;
+	erofs_off_t tar_offset, dataoff;
 
 	struct tar_header *th;
 	struct erofs_dentry *d;
@@ -691,7 +678,7 @@ restart:
 		cksum += (unsigned int)((u8*)th)[j];
 		ckksum += (int)((char*)th)[j];
 	}
-	if (csum != cksum && csum != ckksum) {
+	if (!tar->ddtaridx_mode && csum != cksum && csum != ckksum) {
 		erofs_err("chksum mismatch @ %llu", tar_offset);
 		ret = -EBADMSG;
 		goto out;
@@ -770,7 +757,7 @@ restart:
 			path[--j] = '\0';
 	}
 
-	data_offset = tar->offset;
+	dataoff = tar->offset;
 	tar->offset += st.st_size;
 	switch(th->typeflag) {
 	case '0':
@@ -860,7 +847,7 @@ restart:
 
 	/* EROFS metadata index referring to the original tar data */
 	if (tar->index_mode && sbi->extra_devices &&
-	    erofs_blkoff(sbi, data_offset)) {
+	    erofs_blkoff(sbi, dataoff)) {
 		erofs_err("invalid tar data alignment @ %llu", tar_offset);
 		ret = -EIO;
 		goto out;
@@ -985,16 +972,21 @@ new_inode:
 		} else if (inode->i_size) {
 			if (tar->headeronly_mode) {
 				ret = erofs_write_zero_inode(inode);
+			} else if (tar->ddtaridx_mode) {
+				dataoff = le64_to_cpu(*(__le64 *)(th->devmajor));
+				ret = tarerofs_write_chunkes(inode, dataoff);
 			} else if (tar->rvsp_mode) {
 				inode->datasource = EROFS_INODE_DATA_SOURCE_RESVSP;
-				inode->i_ino[1] = data_offset;
+				inode->i_ino[1] = dataoff;
 				if (erofs_iostream_lskip(&tar->ios, inode->i_size))
 					ret = -EIO;
 				else
 					ret = 0;
 			} else if (tar->index_mode) {
-				ret = tarerofs_write_file_index(inode, tar,
-								data_offset);
+				ret = tarerofs_write_chunkes(inode, dataoff);
+				if (!ret && erofs_iostream_lskip(&tar->ios,
+								 inode->i_size))
+					ret = -EIO;
 			} else {
 				ret = tarerofs_write_file_data(inode, tar);
 			}
-- 
2.43.5



More information about the Linux-erofs mailing list