Linux-EROFS Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/5] erofs-utils: add missing device_id derivation for flattened devices
@ 2026-09-02  2:50 Gao Xiang
  2026-09-02  2:50 ` [PATCH 2/5] erofs-utils: lib: unexport "erofs/chunk.h" Gao Xiang
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Gao Xiang @ 2026-09-02  2:50 UTC (permalink / raw)
  To: linux-erofs; +Cc: Yifan Zhao, Gao Xiang

It will be used for metadata-only flat inode layouts.

Fixes: 0ce853a011238 ("erofs-utils: fuse: add multiple device support")
Signed-off-by: Gao Xiang <xiang@kernel.org>
---
 lib/data.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/data.c b/lib/data.c
index 1bb9269..5a17af5 100644
--- a/lib/data.c
+++ b/lib/data.c
@@ -184,6 +184,7 @@ int erofs_map_dev(struct erofs_sb_info *sbi, struct erofs_map_dev *map)
 			if (map->m_pa >= startoff &&
 			    map->m_pa < startoff + length) {
 				map->m_pa -= startoff;
+				map->m_deviceid = id + 1;
 				break;
 			}
 		}
-- 
2.47.3



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/5] erofs-utils: lib: unexport "erofs/chunk.h"
  2026-09-02  2:50 [PATCH 1/5] erofs-utils: add missing device_id derivation for flattened devices Gao Xiang
@ 2026-09-02  2:50 ` Gao Xiang
  2026-09-02  2:50 ` [PATCH 3/5] erofs-utils: lib: migrate `c_chunkbits` and `c_blobdev_path` Gao Xiang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Gao Xiang @ 2026-09-02  2:50 UTC (permalink / raw)
  To: linux-erofs; +Cc: Yifan Zhao, Gao Xiang

Signed-off-by: Gao Xiang <xiang@kernel.org>
---
 lib/Makefile.am                                   | 2 +-
 lib/blobchunk.c                                   | 4 ++--
 lib/inode.c                                       | 2 +-
 include/erofs/blobchunk.h => lib/liberofs_chunk.h | 4 ++--
 lib/rebuild.c                                     | 2 +-
 lib/remotes/s3.c                                  | 2 +-
 lib/super.c                                       | 2 ++
 lib/tar.c                                         | 2 +-
 mkfs/main.c                                       | 3 +--
 9 files changed, 12 insertions(+), 11 deletions(-)
 rename include/erofs/blobchunk.h => lib/liberofs_chunk.h (92%)

diff --git a/lib/Makefile.am b/lib/Makefile.am
index 25d08f2..0a82915 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -2,7 +2,6 @@
 
 noinst_LTLIBRARIES = liberofs.la
 noinst_HEADERS = $(top_srcdir)/include/erofs_fs.h \
-      $(top_srcdir)/include/erofs/blobchunk.h \
       $(top_srcdir)/include/erofs/block_list.h \
       $(top_srcdir)/include/erofs/config.h \
       $(top_srcdir)/include/erofs/decompress.h \
@@ -23,6 +22,7 @@ noinst_HEADERS = $(top_srcdir)/include/erofs_fs.h \
       $(top_srcdir)/include/erofs/importer.h \
       $(top_srcdir)/lib/liberofs_base64.h \
       $(top_srcdir)/lib/liberofs_cache.h \
+      $(top_srcdir)/lib/liberofs_chunk.h \
       $(top_srcdir)/lib/liberofs_compress.h \
       $(top_srcdir)/lib/liberofs_fragments.h \
       $(top_srcdir)/lib/liberofs_private.h \
diff --git a/lib/blobchunk.c b/lib/blobchunk.c
index 480629f..d218b38 100644
--- a/lib/blobchunk.c
+++ b/lib/blobchunk.c
@@ -6,10 +6,10 @@
  */
 #define _GNU_SOURCE
 #include "erofs/print.h"
-#include "erofs/blobchunk.h"
 #include "erofs/block_list.h"
 #include "erofs/importer.h"
 #include "liberofs_cache.h"
+#include "liberofs_chunk.h"
 #include "liberofs_private.h"
 #include "liberofs_sha256.h"
 #include <unistd.h>
@@ -665,7 +665,7 @@ err_out:
 	return ret;
 }
 
-int erofs_blob_exit(struct erofs_sb_info *sbi)
+int erofs_chunkmgr_exit(struct erofs_sb_info *sbi)
 {
 	struct erofs_chunkmgr *cmgr = sbi->chunkmgr;
 	struct erofs_chunkitem *bc, *n;
diff --git a/lib/inode.c b/lib/inode.c
index a69439c..ea3277b 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -23,9 +23,9 @@
 #include "erofs/exclude.h"
 #include "erofs/block_list.h"
 #include "erofs/compress_hints.h"
-#include "erofs/blobchunk.h"
 #include "erofs/importer.h"
 #include "liberofs_cache.h"
+#include "liberofs_chunk.h"
 #include "liberofs_compress.h"
 #include "liberofs_fragments.h"
 #include "liberofs_metabox.h"
diff --git a/include/erofs/blobchunk.h b/lib/liberofs_chunk.h
similarity index 92%
rename from include/erofs/blobchunk.h
rename to lib/liberofs_chunk.h
index 1c8d77d..3af88df 100644
--- a/include/erofs/blobchunk.h
+++ b/lib/liberofs_chunk.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0+ OR MIT */
 /*
- * erofs-utils/lib/blobchunk.h
+ * erofs-utils/lib/liberofs_chunk.h
  *
  * Copyright (C) 2021, Alibaba Cloud
  */
@@ -25,10 +25,10 @@ int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd,
 int erofs_write_zero_inode(struct erofs_inode *inode);
 int tarerofs_write_chunkes(struct erofs_inode *inode, erofs_off_t data_offset);
 int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi);
-int erofs_blob_exit(struct erofs_sb_info *sbi);
 int erofs_blob_init(struct erofs_sb_info *sbi, int blobdev_id,
 		    unsigned int chunkbits_def);
 int erofs_blob_init_device(struct erofs_sb_info *sbi, int device_id);
+int erofs_chunkmgr_exit(struct erofs_sb_info *sbi);
 
 #ifdef __cplusplus
 }
diff --git a/lib/rebuild.c b/lib/rebuild.c
index 55681f9..38ced3c 100644
--- a/lib/rebuild.c
+++ b/lib/rebuild.c
@@ -12,9 +12,9 @@
 #include "erofs/inode.h"
 #include "erofs/dir.h"
 #include "erofs/xattr.h"
-#include "erofs/blobchunk.h"
 #include "erofs/internal.h"
 #include "erofs/io.h"
+#include "liberofs_chunk.h"
 #include "liberofs_rebuild.h"
 #include "liberofs_uuid.h"
 
diff --git a/lib/remotes/s3.c b/lib/remotes/s3.c
index 245efe5..b3352df 100644
--- a/lib/remotes/s3.c
+++ b/lib/remotes/s3.c
@@ -15,7 +15,7 @@
 #include "erofs/internal.h"
 #include "erofs/print.h"
 #include "erofs/inode.h"
-#include "erofs/blobchunk.h"
+#include "../liberofs_chunk.h"
 #include "erofs/diskbuf.h"
 #include "erofs/importer.h"
 #include "liberofs_rebuild.h"
diff --git a/lib/super.c b/lib/super.c
index 98e1711..9e52dd8 100644
--- a/lib/super.c
+++ b/lib/super.c
@@ -7,6 +7,7 @@
 #include "erofs/print.h"
 #include "erofs/xattr.h"
 #include "liberofs_cache.h"
+#include "liberofs_chunk.h"
 #include "liberofs_compress.h"
 #include "liberofs_metabox.h"
 
@@ -185,6 +186,7 @@ int erofs_read_superblock(struct erofs_sb_info *sbi)
 
 void erofs_put_super(struct erofs_sb_info *sbi)
 {
+	erofs_chunkmgr_exit(sbi);
 	if (sbi->devs) {
 		int i;
 
diff --git a/lib/tar.c b/lib/tar.c
index cf60b02..cbe9f40 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -9,7 +9,6 @@
 #include "erofs/list.h"
 #include "erofs/tar.h"
 #include "erofs/xattr.h"
-#include "erofs/blobchunk.h"
 #include "erofs/importer.h"
 #if defined(HAVE_SYS_SYSMACROS_H)
 #include <sys/sysmacros.h>
@@ -19,6 +18,7 @@
 #endif
 #include "liberofs_base64.h"
 #include "liberofs_cache.h"
+#include "liberofs_chunk.h"
 #include "liberofs_gzran.h"
 #include "liberofs_rebuild.h"
 #include "liberofs_sha256.h"
diff --git a/mkfs/main.c b/mkfs/main.c
index b6d215b..8da3753 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -24,8 +24,8 @@
 #include "erofs/exclude.h"
 #include "erofs/block_list.h"
 #include "erofs/compress_hints.h"
-#include "erofs/blobchunk.h"
 #include "../lib/compressor.h"
+#include "../lib/liberofs_chunk.h"
 #include "../lib/liberofs_gzran.h"
 #include "../lib/liberofs_metabox.h"
 #include "../lib/liberofs_oci.h"
@@ -2084,7 +2084,6 @@ exit:
 		fclose(blklst);
 	erofs_cleanup_compress_hints();
 	erofs_cleanup_exclude_rules();
-	erofs_blob_exit(&g_sbi);
 	erofs_xattr_cleanup_name_prefixes();
 	erofs_rebuild_cleanup();
 	erofs_diskbuf_exit();
-- 
2.47.3



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/5] erofs-utils: lib: migrate `c_chunkbits` and `c_blobdev_path`
  2026-09-02  2:50 [PATCH 1/5] erofs-utils: add missing device_id derivation for flattened devices Gao Xiang
  2026-09-02  2:50 ` [PATCH 2/5] erofs-utils: lib: unexport "erofs/chunk.h" Gao Xiang
@ 2026-09-02  2:50 ` Gao Xiang
  2026-09-02  7:14   ` Zhan Xusheng
  2026-09-02  2:50 ` [PATCH 4/5] erofs-utils: mkfs: introduce ddev_id_def Gao Xiang
  2026-09-02  2:50 ` [PATCH 5/5] erofs-utils: mkfs: enable `--blobdev` for flat inode layouts Gao Xiang
  3 siblings, 1 reply; 8+ messages in thread
From: Gao Xiang @ 2026-09-02  2:50 UTC (permalink / raw)
  To: linux-erofs; +Cc: Yifan Zhao, Gao Xiang

Signed-off-by: Gao Xiang <xiang@kernel.org>
---
 include/erofs/config.h   |  2 --
 include/erofs/importer.h |  1 +
 lib/inode.c              | 25 ++++++++++++++-----------
 mkfs/main.c              | 37 ++++++++++++++++++++-----------------
 4 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/include/erofs/config.h b/include/erofs/config.h
index 95d7e9f..c796c95 100644
--- a/include/erofs/config.h
+++ b/include/erofs/config.h
@@ -34,7 +34,6 @@ struct erofs_configure {
 	int c_dbg_lvl;
 	bool c_dry_run;
 	char c_timeinherit;
-	char c_chunkbits;
 	char c_dedupe;
 	bool c_showprogress;
 	bool c_extra_ea_name_prefixes;
@@ -46,7 +45,6 @@ struct erofs_configure {
 	/* related arguments for mkfs.erofs */
 	char *c_img_path;
 	char *c_src_path;
-	char *c_blobdev_path;
 	char *c_compress_hints_file;
 	char c_force_chunkformat;
 	u8 c_mkfs_metabox_algid;
diff --git a/include/erofs/importer.h b/include/erofs/importer.h
index 07e40b4..c09b169 100644
--- a/include/erofs/importer.h
+++ b/include/erofs/importer.h
@@ -63,6 +63,7 @@ struct erofs_importer_params {
 	bool all_fragments;
 	bool compress_dir;
 	char fragdedupe;
+	char chunkszbits_def;
 };
 
 struct erofs_importer {
diff --git a/lib/inode.c b/lib/inode.c
index ea3277b..728040a 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -704,13 +704,15 @@ static int erofs_write_unencoded_data(struct erofs_inode *inode,
 	return 0;
 }
 
-int erofs_write_unencoded_file(struct erofs_inode *inode, int fd, u64 fpos)
+static int erofs_write_unencoded_file(const struct erofs_importer *im,
+				      struct erofs_inode *inode, int fd, u64 fpos)
 {
 	struct erofs_vfile vf = { .fd = fd };
+	char chunkbits = im->params->chunkszbits_def;
 
-	if (cfg.c_chunkbits &&
+	if (chunkbits &&
 	    inode->datasource != EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) {
-		inode->u.chunkbits = cfg.c_chunkbits;
+		inode->u.chunkbits = chunkbits;
 		/* chunk indexes when explicitly specified */
 		inode->u.chunkformat = 0;
 		if (cfg.c_force_chunkformat == FORCE_INODE_CHUNK_INDEXES)
@@ -1491,6 +1493,11 @@ static int erofs_inode_reserve_data_blocks(struct erofs_inode *inode)
 	return 0;
 }
 
+struct erofs_mkfs_btctx {
+	struct erofs_importer *im;
+	bool rebuild, incremental;
+};
+
 struct erofs_mkfs_job_ndir_ctx {
 	struct erofs_inode *inode;
 	void *ictx;
@@ -1498,7 +1505,8 @@ struct erofs_mkfs_job_ndir_ctx {
 	u64 fpos;
 };
 
-static int erofs_mkfs_job_write_file(struct erofs_mkfs_job_ndir_ctx *ctx)
+static int erofs_mkfs_job_write_file(const struct erofs_mkfs_btctx *btctx,
+				     struct erofs_mkfs_job_ndir_ctx *ctx)
 {
 	struct erofs_inode *inode = ctx->inode;
 	int ret;
@@ -1519,7 +1527,7 @@ static int erofs_mkfs_job_write_file(struct erofs_mkfs_job_ndir_ctx *ctx)
 		}
 	}
 	/* fallback to all data uncompressed */
-	ret = erofs_write_unencoded_file(inode, ctx->fd, ctx->fpos);
+	ret = erofs_write_unencoded_file(btctx->im, inode, ctx->fd, ctx->fpos);
 out:
 	if (inode->datasource == EROFS_INODE_DATA_SOURCE_DISKBUF) {
 		erofs_diskbuf_close(inode->i_diskbuf);
@@ -1539,11 +1547,6 @@ out:
 	return ret;
 }
 
-struct erofs_mkfs_btctx {
-	struct erofs_importer *im;
-	bool rebuild, incremental;
-};
-
 static int erofs_mkfs_handle_nondirectory(const struct erofs_mkfs_btctx *btctx,
 					  struct erofs_mkfs_job_ndir_ctx *ctx)
 {
@@ -1575,7 +1578,7 @@ static int erofs_mkfs_handle_nondirectory(const struct erofs_mkfs_btctx *btctx,
 		if (inode->datasource == EROFS_INODE_DATA_SOURCE_RESVSP)
 			ret = erofs_inode_reserve_data_blocks(inode);
 		else if (ctx->fd >= 0)
-			ret = erofs_mkfs_job_write_file(ctx);
+			ret = erofs_mkfs_job_write_file(btctx, ctx);
 	}
 	if (ret)
 		return ret;
diff --git a/mkfs/main.c b/mkfs/main.c
index 8da3753..c0766d8 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -282,9 +282,11 @@ static void version(void)
 
 static struct erofsmkfs_cfg {
 	struct z_erofs_paramset zcfgs[EROFS_MAX_COMPR_CFGS + 1];
+	char *blobdev_path;
 	/* < 0, xattr disabled and >= INT_MAX, always use inline xattrs */
 	long inlinexattr_tolerance;
 	bool inode_metazone;
+	char chunkbits;
 	u64 unix_timestamp;
 	unsigned int total_zcfgs;
 } mkfscfg = {
@@ -1265,8 +1267,8 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 				erofs_err("invalid chunksize %s", optarg);
 				return -EINVAL;
 			}
-			cfg.c_chunkbits = ilog2(i);
-			if ((1 << cfg.c_chunkbits) != i) {
+			mkfscfg.chunkbits = ilog2(i);
+			if ((1 << mkfscfg.chunkbits) != i) {
 				erofs_err("chunksize %s must be a power of two",
 					  optarg);
 				return -EINVAL;
@@ -1277,7 +1279,7 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 			quiet = true;
 			break;
 		case 13:
-			cfg.c_blobdev_path = optarg;
+			mkfscfg.blobdev_path = optarg;
 			break;
 		case 14:
 			params->ignore_mtime = true;
@@ -1506,13 +1508,13 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 		}
 	}
 
-	if (cfg.c_blobdev_path && cfg.c_chunkbits < mkfs_blkszbits) {
+	if (mkfscfg.blobdev_path && mkfscfg.chunkbits < mkfs_blkszbits) {
 		erofs_err("--blobdev must be used together with --chunksize");
 		return -EINVAL;
 	}
 
 	/* TODO: can be implemented with (deviceslot) mapped_blkaddr */
-	if (cfg.c_blobdev_path &&
+	if (mkfscfg.blobdev_path &&
 	    cfg.c_force_chunkformat == FORCE_INODE_BLOCK_MAP) {
 		erofs_err("--blobdev cannot work with block map currently");
 		return -EINVAL;
@@ -1564,9 +1566,9 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 		params->pclusterblks_max = pclustersize_max >> mkfs_blkszbits;
 		params->pclusterblks_def = params->pclusterblks_max;
 	}
-	if (cfg.c_chunkbits && cfg.c_chunkbits < mkfs_blkszbits) {
+	if (mkfscfg.chunkbits && mkfscfg.chunkbits < mkfs_blkszbits) {
 		erofs_err("chunksize %u must be larger than block size",
-			  1u << cfg.c_chunkbits);
+			  1u << mkfscfg.chunkbits);
 		return -EINVAL;
 	}
 
@@ -1579,10 +1581,10 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 	 * unaligned. Therefore, let's issue a warning here and still skip
 	 * alignment for now.
 	 */
-	if (cfg.c_chunkbits && dsunit &&
-	    (1u << (cfg.c_chunkbits - g_sbi.blkszbits)) < dsunit) {
+	if (mkfscfg.chunkbits && dsunit &&
+	    (1u << (mkfscfg.chunkbits - g_sbi.blkszbits)) < dsunit) {
 		erofs_warn("chunksize %u bytes is smaller than dsunit %u blocks, ignore dsunit !",
-			   1u << cfg.c_chunkbits, dsunit);
+			   1u << mkfscfg.chunkbits, dsunit);
 	}
 
 	if (pclustersize_packed) {
@@ -1896,6 +1898,7 @@ int main(int argc, char **argv)
 	importer_params.source = cfg.c_src_path;
 	importer_params.no_datainline = mkfs_no_datainline;
 	importer_params.dot_omitted = mkfs_dot_omitted;
+	importer_params.chunkszbits_def = mkfscfg.chunkbits;
 	err = erofs_importer_init(&importer);
 	if (err)
 		goto exit;
@@ -1903,7 +1906,7 @@ int main(int argc, char **argv)
 	if (importer_params.dedupe == EROFS_DEDUPE_FORCE_ON) {
 		if (!g_sbi.available_compr_algs) {
 			erofs_err("Compression is not enabled.  Turn on chunk-based data deduplication instead.");
-			cfg.c_chunkbits = g_sbi.blkszbits;
+			mkfscfg.chunkbits = g_sbi.blkszbits;
 		} else {
 			err = z_erofs_dedupe_init(erofs_blksiz(&g_sbi));
 			if (err) {
@@ -1915,7 +1918,7 @@ int main(int argc, char **argv)
 	}
 
 	cfg.c_dedupe = importer_params.dedupe;
-	if (tar_index_512b || cfg.c_blobdev_path) {
+	if (tar_index_512b || mkfscfg.blobdev_path) {
 		err = erofs_mkfs_init_devices(&g_sbi, 1);
 		if (err) {
 			erofs_err("failed to generate device table: %s",
@@ -1924,9 +1927,9 @@ int main(int argc, char **argv)
 		}
 	}
 
-	if (tar_index_512b || cfg.c_chunkbits) {
-		if (g_sbi.extra_devices && cfg.c_blobdev_path) {
-			g_sbi.devs[0].src_path = strdup(cfg.c_blobdev_path);
+	if (tar_index_512b || mkfscfg.chunkbits) {
+		if (g_sbi.extra_devices && mkfscfg.blobdev_path) {
+			g_sbi.devs[0].src_path = strdup(mkfscfg.blobdev_path);
 			if (!g_sbi.devs[0].src_path) {
 				err = -ENOMEM;
 				goto exit;
@@ -1937,7 +1940,7 @@ int main(int argc, char **argv)
 				goto exit;
 
 		}
-		err = erofs_blob_init(&g_sbi, cfg.c_blobdev_path ? 1 : 0, cfg.c_chunkbits);
+		err = erofs_blob_init(&g_sbi, mkfscfg.blobdev_path ? 1 : 0, mkfscfg.chunkbits);
 		if (err)
 			goto exit;
 	}
@@ -2047,7 +2050,7 @@ int main(int argc, char **argv)
 		}
 	}
 
-	if (erofstar.index_mode || cfg.c_chunkbits || g_sbi.extra_devices) {
+	if (erofstar.index_mode || mkfscfg.chunkbits || g_sbi.extra_devices) {
 		err = erofs_mkfs_dump_blobs(&g_sbi);
 		if (err)
 			goto exit;
-- 
2.47.3



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/5] erofs-utils: mkfs: introduce ddev_id_def
  2026-09-02  2:50 [PATCH 1/5] erofs-utils: add missing device_id derivation for flattened devices Gao Xiang
  2026-09-02  2:50 ` [PATCH 2/5] erofs-utils: lib: unexport "erofs/chunk.h" Gao Xiang
  2026-09-02  2:50 ` [PATCH 3/5] erofs-utils: lib: migrate `c_chunkbits` and `c_blobdev_path` Gao Xiang
@ 2026-09-02  2:50 ` Gao Xiang
  2026-09-02  2:50 ` [PATCH 5/5] erofs-utils: mkfs: enable `--blobdev` for flat inode layouts Gao Xiang
  3 siblings, 0 replies; 8+ messages in thread
From: Gao Xiang @ 2026-09-02  2:50 UTC (permalink / raw)
  To: linux-erofs; +Cc: Yifan Zhao, Gao Xiang

It indicates the default blob device containing the inode data.

Signed-off-by: Gao Xiang <xiang@kernel.org>
---
 include/erofs/importer.h |  1 +
 lib/blobchunk.c          | 11 +++--------
 lib/inode.c              |  3 ++-
 lib/liberofs_chunk.h     |  5 ++---
 mkfs/main.c              |  3 ++-
 5 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/include/erofs/importer.h b/include/erofs/importer.h
index c09b169..5141965 100644
--- a/include/erofs/importer.h
+++ b/include/erofs/importer.h
@@ -64,6 +64,7 @@ struct erofs_importer_params {
 	bool compress_dir;
 	char fragdedupe;
 	char chunkszbits_def;
+	u16 ddev_id_def;		/* target device id for inode data */
 };
 
 struct erofs_importer {
diff --git a/lib/blobchunk.c b/lib/blobchunk.c
index d218b38..3a641f3 100644
--- a/lib/blobchunk.c
+++ b/lib/blobchunk.c
@@ -34,7 +34,6 @@ struct erofs_chunkitem erofs_holechunk = {
 struct erofs_chunkmgr {
 	struct list_head chunks[65536];
 	struct list_head unhashed_chunks;
-	int device_id;
 };
 
 #define EROFS_CHUNK_NR_BUCKETS	\
@@ -49,7 +48,7 @@ struct erofs_chunkitem *erofs_get_unhashed_chunk(struct erofs_sb_info *sbi,
 	int ret;
 
 	if (__erofs_unlikely(!chunkmgr)) {
-		ret = erofs_blob_init(sbi, 0, 0);
+		ret = erofs_blob_init(sbi, 0);
 		if (ret)
 			return ERR_PTR(ret);
 		chunkmgr = sbi->chunkmgr;
@@ -323,11 +322,9 @@ static bool erofs_blob_can_merge(struct erofs_sb_info *sbi,
 }
 
 int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd,
-				  erofs_off_t startoff)
+				  erofs_off_t startoff, int device_id)
 {
 	struct erofs_sb_info *sbi = inode->sbi;
-	struct erofs_chunkmgr *cmgr = sbi->chunkmgr;
-	int device_id = cmgr->device_id;
 	unsigned int chunkbits = inode->u.chunkbits;
 	unsigned int count, unit;
 	struct erofs_chunkitem *chunk, *lastch;
@@ -636,8 +633,7 @@ err_vf:
 	return ret;
 }
 
-int erofs_blob_init(struct erofs_sb_info *sbi, int blobdev_id,
-		    unsigned int chunkbits_zero)
+int erofs_blob_init(struct erofs_sb_info *sbi, unsigned int chunkbits_zero)
 {
 	struct erofs_chunkmgr *cmgr;
 	int i, ret;
@@ -656,7 +652,6 @@ int erofs_blob_init(struct erofs_sb_info *sbi, int blobdev_id,
 			if (ret)
 				goto err_out;
 		}
-		cmgr->device_id = blobdev_id;
 		sbi->chunkmgr = cmgr;
 	}
 	return 0;
diff --git a/lib/inode.c b/lib/inode.c
index 728040a..a3fc181 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -709,6 +709,7 @@ static int erofs_write_unencoded_file(const struct erofs_importer *im,
 {
 	struct erofs_vfile vf = { .fd = fd };
 	char chunkbits = im->params->chunkszbits_def;
+	int device_id = im->params->ddev_id_def;
 
 	if (chunkbits &&
 	    inode->datasource != EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) {
@@ -717,7 +718,7 @@ static int erofs_write_unencoded_file(const struct erofs_importer *im,
 		inode->u.chunkformat = 0;
 		if (cfg.c_force_chunkformat == FORCE_INODE_CHUNK_INDEXES)
 			inode->u.chunkformat = EROFS_CHUNK_FORMAT_INDEXES;
-		return erofs_blob_write_chunked_file(inode, fd, fpos);
+		return erofs_blob_write_chunked_file(inode, fd, fpos, device_id);
 	}
 
 	if (inode->datasource == EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) {
diff --git a/lib/liberofs_chunk.h b/lib/liberofs_chunk.h
index 3af88df..ff31891 100644
--- a/lib/liberofs_chunk.h
+++ b/lib/liberofs_chunk.h
@@ -21,12 +21,11 @@ void erofs_inode_fixup_chunkformat(struct erofs_inode *inode);
 int erofs_write_chunk_indexes(struct erofs_inode *inode, struct erofs_vfile *vf,
 			      erofs_off_t off);
 int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd,
-				  erofs_off_t startoff);
+				  erofs_off_t startoff, int device_id);
 int erofs_write_zero_inode(struct erofs_inode *inode);
 int tarerofs_write_chunkes(struct erofs_inode *inode, erofs_off_t data_offset);
 int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi);
-int erofs_blob_init(struct erofs_sb_info *sbi, int blobdev_id,
-		    unsigned int chunkbits_def);
+int erofs_blob_init(struct erofs_sb_info *sbi, unsigned int chunkbits_zero);
 int erofs_blob_init_device(struct erofs_sb_info *sbi, int device_id);
 int erofs_chunkmgr_exit(struct erofs_sb_info *sbi);
 
diff --git a/mkfs/main.c b/mkfs/main.c
index c0766d8..6b32e90 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -1940,7 +1940,8 @@ int main(int argc, char **argv)
 				goto exit;
 
 		}
-		err = erofs_blob_init(&g_sbi, mkfscfg.blobdev_path ? 1 : 0, mkfscfg.chunkbits);
+		importer_params.ddev_id_def = mkfscfg.blobdev_path ? 1 : 0;
+		err = erofs_blob_init(&g_sbi, mkfscfg.chunkbits);
 		if (err)
 			goto exit;
 	}
-- 
2.47.3



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/5] erofs-utils: mkfs: enable `--blobdev` for flat inode layouts
  2026-09-02  2:50 [PATCH 1/5] erofs-utils: add missing device_id derivation for flattened devices Gao Xiang
                   ` (2 preceding siblings ...)
  2026-09-02  2:50 ` [PATCH 4/5] erofs-utils: mkfs: introduce ddev_id_def Gao Xiang
@ 2026-09-02  2:50 ` Gao Xiang
  2026-09-02  8:11   ` Zhan Xusheng
  3 siblings, 1 reply; 8+ messages in thread
From: Gao Xiang @ 2026-09-02  2:50 UTC (permalink / raw)
  To: linux-erofs; +Cc: Yifan Zhao, Gao Xiang

Add metadata-only image support for PLAIN/INLINE inode layouts:
 $ mkfs.erofs --blobdev blob.erofs fsmeta.erofs foo/

Follow-up: add `--blobdev` support for compressed inode layouts.

Signed-off-by: Gao Xiang <xiang@kernel.org>
---
 include/erofs/inode.h    |  2 +-
 include/erofs/internal.h |  1 +
 lib/blobchunk.c          | 12 ----------
 lib/importer.c           |  5 +++++
 lib/inode.c              | 48 ++++++++++++++++++++++++----------------
 lib/liberofs_chunk.h     |  1 -
 lib/remotes/s3.c         |  2 +-
 lib/super.c              | 37 ++++++++++++++++++++-----------
 lib/tar.c                |  2 +-
 mkfs/main.c              | 24 ++++++++------------
 10 files changed, 71 insertions(+), 63 deletions(-)

diff --git a/include/erofs/inode.h b/include/erofs/inode.h
index bf089e8..23848e8 100644
--- a/include/erofs/inode.h
+++ b/include/erofs/inode.h
@@ -39,7 +39,7 @@ int erofs_iflush(struct erofs_inode *inode);
 struct erofs_dentry *erofs_d_alloc(struct erofs_inode *parent,
 				   const char *name);
 int erofs_allocate_inode_bh_data(struct erofs_inode *inode, erofs_blk_t nblocks,
-				 bool in_metazone);
+				 int device_id);
 bool erofs_dentry_is_wht(struct erofs_sb_info *sbi, struct erofs_dentry *d);
 int __erofs_fill_inode(struct erofs_importer *im, struct erofs_inode *inode,
 		       struct stat *st, const char *path);
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 95f5627..4d09c58 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -461,6 +461,7 @@ void erofs_put_super(struct erofs_sb_info *sbi);
 int erofs_writesb(struct erofs_sb_info *sbi);
 struct erofs_buffer_head *erofs_reserve_sb(struct erofs_bufmgr *bmgr);
 int erofs_mkfs_init_devices(struct erofs_sb_info *sbi, unsigned int devices);
+int erofs_update_all_devices(struct erofs_sb_info *sbi);
 int erofs_write_device_table(struct erofs_sb_info *sbi);
 int erofs_enable_sb_chksum(struct erofs_sb_info *sbi, u32 *crc);
 int erofs_superblock_csum_verify(struct erofs_sb_info *sbi);
diff --git a/lib/blobchunk.c b/lib/blobchunk.c
index 3a641f3..47a0c05 100644
--- a/lib/blobchunk.c
+++ b/lib/blobchunk.c
@@ -554,18 +554,6 @@ int tarerofs_write_chunkes(struct erofs_inode *inode, erofs_off_t data_offset)
 	return 0;
 }
 
-int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi)
-{
-	struct erofs_device_info *di;
-
-	for (di = sbi->devs; di < sbi->devs + sbi->extra_devices; ++di) {
-		if (!di->bmgr)
-			continue;
-		di->blocks = erofs_mapbh(di->bmgr, NULL);
-	}
-	return 0;
-}
-
 static int erofs_insert_zerochunk(struct erofs_chunkmgr *cmgr,
 				  unsigned int cbitsdef)
 {
diff --git a/lib/importer.c b/lib/importer.c
index 2a635d2..89d4d8b 100644
--- a/lib/importer.c
+++ b/lib/importer.c
@@ -127,6 +127,11 @@ int erofs_importer_flush_all(struct erofs_importer *im)
 	fsalignblks = im->params->fsalignblks ?
 		roundup_pow_of_two(im->params->fsalignblks) : 1;
 	sbi->dif0.blocks = roundup(erofs_mapbh(sbi->bmgr, NULL), fsalignblks);
+
+	err = erofs_update_all_devices(sbi);
+	if (err)
+		return err;
+
 	err = erofs_write_device_table(sbi);
 	if (err)
 		return err;
diff --git a/lib/inode.c b/lib/inode.c
index a3fc181..b3aa066 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -198,26 +198,33 @@ struct erofs_dentry *erofs_d_alloc(struct erofs_inode *parent,
 
 /* allocate main data for an inode */
 int erofs_allocate_inode_bh_data(struct erofs_inode *inode, erofs_blk_t nblocks,
-				 bool in_metazone)
+				 int device_id)
 {
 	struct erofs_sb_info *sbi = inode->sbi;
-	struct erofs_bufmgr *bmgr = in_metazone ?
+	struct erofs_bufmgr *bmgr = device_id ?
 		erofs_metadata_bmgr(sbi, false) : sbi->bmgr;
 	struct erofs_buffer_head *bh;
 	int ret, type;
 
+	if (device_id < 0)
+		bmgr = erofs_metadata_bmgr(sbi, false);
+	else if (!device_id)
+		bmgr = sbi->bmgr;
+	else
+		bmgr = sbi->devs[device_id - 1].bmgr;
+
+	if (!bmgr) {
+		erofs_err("cannot allocate data in unavailable device %d for %s",
+			  device_id, inode->i_srcpath);
+		return -EINVAL;
+	}
+
 	if (!nblocks) {
 		/* it has only tail-end data */
 		inode->u.i_blkaddr = EROFS_NULL_ADDR;
 		return 0;
 	}
 
-	if (in_metazone && !bmgr) {
-		erofs_err("cannot allocate data in the metazone when unavailable for %s",
-			  inode->i_srcpath);
-		return -EINVAL;
-	}
-
 	/* allocate main data buffer */
 	type = S_ISDIR(inode->i_mode) ? DIRA : DATA;
 	bh = erofs_balloc(bmgr, type, erofs_pos(sbi, nblocks), 0);
@@ -232,8 +239,10 @@ int erofs_allocate_inode_bh_data(struct erofs_inode *inode, erofs_blk_t nblocks,
 	DBG_BUGON(ret < 0);
 
 	/* write blocks except for the tail-end block */
-	inode->u.i_blkaddr = bh->block->blkaddr | (in_metazone ?
-		(sbi->extra_devices + 1ULL) << EROFS_I_BLKADDR_DEV_ID_BIT : 0);
+	if (device_id < 0)
+		device_id = sbi->extra_devices + 1;
+	inode->u.i_blkaddr = bh->block->blkaddr |
+		((u64)device_id << EROFS_I_BLKADDR_DEV_ID_BIT);
 	return 0;
 }
 
@@ -604,7 +613,7 @@ int erofs_write_file_from_buffer(struct erofs_inode *inode, char *buf)
 
 	inode->datalayout = EROFS_INODE_FLAT_INLINE;
 
-	ret = erofs_allocate_inode_bh_data(inode, nblocks, false);
+	ret = erofs_allocate_inode_bh_data(inode, nblocks, 0);
 	if (ret)
 		return ret;
 
@@ -635,7 +644,7 @@ static bool erofs_file_is_compressible(struct erofs_importer *im,
 
 static int erofs_write_unencoded_data(struct erofs_inode *inode,
 				      struct erofs_vfile *vf, erofs_off_t fpos,
-				      bool noseek, bool in_metazone)
+				      bool noseek, int device_id)
 {
 	struct erofs_sb_info *sbi = inode->sbi;
 	struct erofs_buffer_head *bh;
@@ -646,7 +655,7 @@ static int erofs_write_unencoded_data(struct erofs_inode *inode,
 
 	if (!noseek && erofs_sb_has_48bit(sbi)) {
 		if (erofs_io_lseek(vf, fpos, SEEK_DATA) == -ENXIO) {
-			ret = erofs_allocate_inode_bh_data(inode, 0, false);
+			ret = erofs_allocate_inode_bh_data(inode, 0, 0);
 			if (ret)
 				return ret;
 			inode->datalayout = EROFS_INODE_FLAT_PLAIN;
@@ -663,7 +672,7 @@ static int erofs_write_unencoded_data(struct erofs_inode *inode,
 	remaining = inode->i_size - inode->idata_size;
 
 	ret = erofs_allocate_inode_bh_data(inode, remaining >> sbi->blkszbits,
-					   in_metazone);
+					   device_id);
 	if (ret)
 		return ret;
 
@@ -724,13 +733,14 @@ static int erofs_write_unencoded_file(const struct erofs_importer *im,
 	if (inode->datasource == EROFS_INODE_DATA_SOURCE_REBUILD_BLOB) {
 		if (erofs_io_lseek(&vf, fpos, SEEK_SET) != (off_t)fpos)
 			return -EIO;
-		return erofs_write_unencoded_data(inode, &vf, fpos, true, false);
+		return erofs_write_unencoded_data(inode, &vf, fpos, true, device_id);
 	}
 
 	inode->datalayout = EROFS_INODE_FLAT_INLINE;
 	/* fallback to all data uncompressed */
 	return erofs_write_unencoded_data(inode, &vf, fpos,
-			inode->datasource == EROFS_INODE_DATA_SOURCE_DISKBUF, false);
+			inode->datasource == EROFS_INODE_DATA_SOURCE_DISKBUF,
+			device_id);
 }
 
 static int erofs_write_dir_file(const struct erofs_importer *im,
@@ -749,7 +759,7 @@ static int erofs_write_dir_file(const struct erofs_importer *im,
 	} else {
 		DBG_BUGON(dir->idata_size != (dir->i_size & (bsz - 1)));
 		err = erofs_write_unencoded_data(dir, vf, 0, true,
-					im->params->dirdata_in_metazone);
+				im->params->dirdata_in_metazone ? -1 : 0);
 	}
 	erofs_io_close(vf);
 	return err;
@@ -1135,7 +1145,7 @@ static int erofs_write_tail_end(struct erofs_importer *im,
 				params->dirdata_in_metazone;
 
 			ret = erofs_allocate_inode_bh_data(inode, 1,
-							   in_metazone);
+					in_metazone ? -1 : params->ddev_id_def);
 			if (ret)
 				return ret;
 			bh = inode->bh_data;
@@ -2412,7 +2422,7 @@ struct erofs_inode *erofs_mkfs_build_special_from_fd(struct erofs_importer *im,
 	ret = erofs_write_unencoded_data(inode,
 			&(struct erofs_vfile){ .fd = fd }, 0,
 			inode->datasource == EROFS_INODE_DATA_SOURCE_DISKBUF,
-			false);
+			0);
 	if (ret)
 		return ERR_PTR(ret);
 out:
diff --git a/lib/liberofs_chunk.h b/lib/liberofs_chunk.h
index ff31891..16f3d05 100644
--- a/lib/liberofs_chunk.h
+++ b/lib/liberofs_chunk.h
@@ -24,7 +24,6 @@ int erofs_blob_write_chunked_file(struct erofs_inode *inode, int fd,
 				  erofs_off_t startoff, int device_id);
 int erofs_write_zero_inode(struct erofs_inode *inode);
 int tarerofs_write_chunkes(struct erofs_inode *inode, erofs_off_t data_offset);
-int erofs_mkfs_dump_blobs(struct erofs_sb_info *sbi);
 int erofs_blob_init(struct erofs_sb_info *sbi, unsigned int chunkbits_zero);
 int erofs_blob_init_device(struct erofs_sb_info *sbi, int device_id);
 int erofs_chunkmgr_exit(struct erofs_sb_info *sbi);
diff --git a/lib/remotes/s3.c b/lib/remotes/s3.c
index b3352df..56ab808 100644
--- a/lib/remotes/s3.c
+++ b/lib/remotes/s3.c
@@ -1058,7 +1058,7 @@ static int s3erofs_remote_getobject(struct erofs_importer *im,
 		inode->idata_size = 0;
 		ret = erofs_allocate_inode_bh_data(inode,
 				DIV_ROUND_UP(inode->i_size, 1U << sbi->blkszbits),
-				false);
+				im->params->ddev_id_def);
 		if (ret)
 			return ret;
 		resp.vf = &sbi->bdev;
diff --git a/lib/super.c b/lib/super.c
index 9e52dd8..2bb22ac 100644
--- a/lib/super.c
+++ b/lib/super.c
@@ -414,15 +414,30 @@ int erofs_mkfs_init_devices(struct erofs_sb_info *sbi, unsigned int devices)
 	return 0;
 }
 
+int erofs_update_all_devices(struct erofs_sb_info *sbi)
+{
+	struct erofs_device_info *di;
+	erofs_blk_t last_uniaddr = sbi->dif0.blocks;
+
+	for (di = sbi->devs; di < sbi->devs + sbi->extra_devices; ++di) {
+		if (di->bmgr)
+			di->blocks = erofs_mapbh(di->bmgr, NULL);
+		di->uniaddr = last_uniaddr;
+		last_uniaddr += di->blocks;
+	}
+	sbi->total_blocks = last_uniaddr;
+	return 0;
+}
+
 int erofs_write_device_table(struct erofs_sb_info *sbi)
 {
-	erofs_blk_t nblocks = sbi->dif0.blocks;
 	struct erofs_buffer_head *bh = sbi->bh_devt;
+	struct erofs_device_info *di = sbi->devs;
 	erofs_off_t pos;
-	unsigned int i, ret;
+	unsigned int ret;
 
 	if (!sbi->extra_devices)
-		goto out;
+		return 0;
 	if (!bh) {
 		if (erofs_sb_has_device_table(sbi))
 			return 0;
@@ -435,28 +450,24 @@ int erofs_write_device_table(struct erofs_sb_info *sbi)
 		return -EINVAL;
 	}
 
-	i = 0;
 	do {
 		struct erofs_deviceslot dis = {
-			.uniaddr_lo = cpu_to_le32(nblocks),
-			.blocks_lo = cpu_to_le32(sbi->devs[i].blocks),
-			.blocks_hi = cpu_to_le16(sbi->devs[i].blocks >> 32),
-			.uniaddr_hi = cpu_to_le16(nblocks >> 32),
+			.uniaddr_lo = cpu_to_le32(di->uniaddr),
+			.blocks_lo = cpu_to_le32(di->blocks),
+			.blocks_hi = cpu_to_le16(di->blocks >> 32),
+			.uniaddr_hi = cpu_to_le16(di->uniaddr >> 32),
 		};
 
-		memcpy(dis.tag, sbi->devs[i].tag, sizeof(dis.tag));
+		memcpy(dis.tag, di->tag, sizeof(dis.tag));
 		ret = erofs_dev_write(sbi, &dis, pos, sizeof(dis));
 		if (ret)
 			return ret;
 		pos += sizeof(dis);
-		nblocks += sbi->devs[i].blocks;
-	} while (++i < sbi->extra_devices);
+	} while (++di < sbi->devs + sbi->extra_devices);
 
 	bh->op = &erofs_drop_directly_bhops;
 	erofs_bdrop(bh, false);
 	sbi->bh_devt = NULL;
-out:
-	sbi->total_blocks = nblocks;
 	return 0;
 }
 
diff --git a/lib/tar.c b/lib/tar.c
index cbe9f40..f027532 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -691,7 +691,7 @@ static int tarerofs_write_uncompressed_file(struct erofs_inode *inode,
 	inode->datalayout = EROFS_INODE_FLAT_PLAIN;
 	nblocks = DIV_ROUND_UP(inode->i_size, 1U << sbi->blkszbits);
 
-	ret = erofs_allocate_inode_bh_data(inode, nblocks, false);
+	ret = erofs_allocate_inode_bh_data(inode, nblocks, 0);
 	if (ret)
 		return ret;
 
diff --git a/mkfs/main.c b/mkfs/main.c
index 6b32e90..4acfb9a 100644
--- a/mkfs/main.c
+++ b/mkfs/main.c
@@ -1508,11 +1508,6 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 		}
 	}
 
-	if (mkfscfg.blobdev_path && mkfscfg.chunkbits < mkfs_blkszbits) {
-		erofs_err("--blobdev must be used together with --chunksize");
-		return -EINVAL;
-	}
-
 	/* TODO: can be implemented with (deviceslot) mapped_blkaddr */
 	if (mkfscfg.blobdev_path &&
 	    cfg.c_force_chunkformat == FORCE_INODE_BLOCK_MAP) {
@@ -1533,6 +1528,11 @@ static int mkfs_parse_options_cfg(struct erofs_importer_params *params,
 		err = mkfs_parse_sources(argc, argv, optind);
 		if (err)
 			return err;
+
+		if (mkfscfg.blobdev_path && source_mode == EROFS_MKFS_SOURCE_REBUILD) {
+			erofs_err("--blobdev is currently incompatible with rebuild mode");
+			return -EINVAL;
+		}
 	} else if (source_mode != EROFS_MKFS_SOURCE_TAR) {
 		erofs_err("missing argument: SOURCE(s)");
 		return -EINVAL;
@@ -1925,10 +1925,7 @@ int main(int argc, char **argv)
 				  erofs_strerror(err));
 			goto exit;
 		}
-	}
-
-	if (tar_index_512b || mkfscfg.chunkbits) {
-		if (g_sbi.extra_devices && mkfscfg.blobdev_path) {
+		if (mkfscfg.blobdev_path) {
 			g_sbi.devs[0].src_path = strdup(mkfscfg.blobdev_path);
 			if (!g_sbi.devs[0].src_path) {
 				err = -ENOMEM;
@@ -1941,6 +1938,9 @@ int main(int argc, char **argv)
 
 		}
 		importer_params.ddev_id_def = mkfscfg.blobdev_path ? 1 : 0;
+	}
+
+	if (tar_index_512b || mkfscfg.chunkbits) {
 		err = erofs_blob_init(&g_sbi, mkfscfg.chunkbits);
 		if (err)
 			goto exit;
@@ -2051,12 +2051,6 @@ int main(int argc, char **argv)
 		}
 	}
 
-	if (erofstar.index_mode || mkfscfg.chunkbits || g_sbi.extra_devices) {
-		err = erofs_mkfs_dump_blobs(&g_sbi);
-		if (err)
-			goto exit;
-	}
-
 	err = erofs_importer_flush_all(&importer);
 	if (err)
 		goto exit;
-- 
2.47.3



^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 3/5] erofs-utils: lib: migrate `c_chunkbits` and `c_blobdev_path`
  2026-09-02  2:50 ` [PATCH 3/5] erofs-utils: lib: migrate `c_chunkbits` and `c_blobdev_path` Gao Xiang
@ 2026-09-02  7:14   ` Zhan Xusheng
  0 siblings, 0 replies; 8+ messages in thread
From: Zhan Xusheng @ 2026-09-02  7:14 UTC (permalink / raw)
  To: xiang; +Cc: linux-erofs, stopire, zhanxusheng

Hi Xiang,

On Wed, Sep 02, 2026 at 10:50:28AM +0800, Gao Xiang wrote:
> +	importer_params.chunkszbits_def = mkfscfg.chunkbits;
>  	err = erofs_importer_init(&importer);

This snapshot is taken eight lines above the dedupe fallback that assigns
mkfscfg.chunkbits = g_sbi.blkszbits, so the fallback no longer reaches
erofs_write_unencoded_file() and the "Turn on chunk-based data
deduplication instead" message stops being true.  erofs_blob_init() and
the condition above it still read mkfscfg.chunkbits, so the blob side is
set up for chunks while no inode gets one.

Eight identical 256 KiB files, no -z so that available_compr_algs is 0:

  mkfs.erofs -Ededupe img dedsrc

  b96836c (2/5)   266240 bytes, datalayout 4
  3dde13e (3/5)  2101248 bytes, datalayout 0

Moving the assignment below that block gives 266240 again.
chunkszbits_def has a single reader and erofs_importer_init() does not
look at it.

Thanks,
Zhan Xusheng


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 5/5] erofs-utils: mkfs: enable `--blobdev` for flat inode layouts
  2026-09-02  2:50 ` [PATCH 5/5] erofs-utils: mkfs: enable `--blobdev` for flat inode layouts Gao Xiang
@ 2026-09-02  8:11   ` Zhan Xusheng
  2026-09-02 15:58     ` Gao Xiang
  0 siblings, 1 reply; 8+ messages in thread
From: Zhan Xusheng @ 2026-09-02  8:11 UTC (permalink / raw)
  To: xiang; +Cc: linux-erofs, stopire, zhanxusheng

Hi Xiang,

--blobdev without --chunksize works here, and fsck.erofs --extract returns
the tree byte for byte.

Two things in erofs_allocate_inode_bh_data().

The bmgr initializer is dead, since the chain below covers all three signs
of device_id, and for device_id > 0 it picks the metazone.

The new message prints the sentinel when the metazone is the unavailable
one.  mkfs.erofs --incremental --MZ over an image built with --MZ:

  e1959e9  cannot allocate data in the metazone when unavailable for ...
  0badea0  cannot allocate data in unavailable device -1 for ...

Both refuse it, so nothing changed there, but "device -1" no longer tells
the user which target was meant.

Thanks,
Zhan Xusheng


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 5/5] erofs-utils: mkfs: enable `--blobdev` for flat inode layouts
  2026-09-02  8:11   ` Zhan Xusheng
@ 2026-09-02 15:58     ` Gao Xiang
  0 siblings, 0 replies; 8+ messages in thread
From: Gao Xiang @ 2026-09-02 15:58 UTC (permalink / raw)
  To: Zhan Xusheng; +Cc: xiang, linux-erofs, stopire, zhanxusheng

Hi Xusheng,

On Wed, Sep 02, 2026 at 04:11:41PM +0800, Zhan Xusheng wrote:
> Hi Xiang,
> 
> --blobdev without --chunksize works here, and fsck.erofs --extract returns
> the tree byte for byte.
> 
> Two things in erofs_allocate_inode_bh_data().
> 
> The bmgr initializer is dead, since the chain below covers all three signs
> of device_id, and for device_id > 0 it picks the metazone.
> 
> The new message prints the sentinel when the metazone is the unavailable
> one.  mkfs.erofs --incremental --MZ over an image built with --MZ:
> 
>   e1959e9  cannot allocate data in the metazone when unavailable for ...
>   0badea0  cannot allocate data in unavailable device -1 for ...
> 
> Both refuse it, so nothing changed there, but "device -1" no longer tells
> the user which target was meant.

Those comments above are hard to follow for me.

Could you just submit patches instead to demo your intention?

I could apply directly if your suggestion makes more sense.

Thanks,
Gao Xiang

> 
> Thanks,
> Zhan Xusheng
> 


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-09-02 15:58 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02  2:50 [PATCH 1/5] erofs-utils: add missing device_id derivation for flattened devices Gao Xiang
2026-09-02  2:50 ` [PATCH 2/5] erofs-utils: lib: unexport "erofs/chunk.h" Gao Xiang
2026-09-02  2:50 ` [PATCH 3/5] erofs-utils: lib: migrate `c_chunkbits` and `c_blobdev_path` Gao Xiang
2026-09-02  7:14   ` Zhan Xusheng
2026-09-02  2:50 ` [PATCH 4/5] erofs-utils: mkfs: introduce ddev_id_def Gao Xiang
2026-09-02  2:50 ` [PATCH 5/5] erofs-utils: mkfs: enable `--blobdev` for flat inode layouts Gao Xiang
2026-09-02  8:11   ` Zhan Xusheng
2026-09-02 15:58     ` Gao Xiang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox