[PATCH v4 5/6] erofs-utils: fsck: support multiple devices

Gao Xiang hsiangkao at linux.alibaba.com
Tue Nov 16 20:49:38 AEDT 2021


Add preliminary multiple device support for fsck feature.

Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
 fsck/main.c | 43 +++++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/fsck/main.c b/fsck/main.c
index b742e3579c59..7bee5605b9df 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -24,6 +24,7 @@ static struct erofsfsck_cfg fsckcfg;
 static struct option long_options[] = {
 	{"help", no_argument, 0, 1},
 	{"extract", no_argument, 0, 2},
+	{"device", required_argument, 0, 3},
 	{0, 0, 0, 0},
 };
 
@@ -34,6 +35,7 @@ static void usage(void)
 	      " -V              print the version number of fsck.erofs and exit.\n"
 	      " -d#             set output message level to # (maximum 9)\n"
 	      " -p              print total compression ratio of all files\n"
+	      " --device=X      specify an extra device to be used together\n"
 	      " --extract       check if all files are well encoded\n"
 	      " --help          display this help and exit.\n",
 	      stderr);
@@ -46,7 +48,7 @@ static void erofsfsck_print_version(void)
 
 static int erofsfsck_parse_options_cfg(int argc, char **argv)
 {
-	int opt, i;
+	int opt, ret;
 
 	while ((opt = getopt_long(argc, argv, "Vd:p",
 				  long_options, NULL)) != -1) {
@@ -55,12 +57,12 @@ static int erofsfsck_parse_options_cfg(int argc, char **argv)
 			erofsfsck_print_version();
 			exit(0);
 		case 'd':
-			i = atoi(optarg);
-			if (i < EROFS_MSG_MIN || i > EROFS_MSG_MAX) {
-				erofs_err("invalid debug level %d", i);
+			ret = atoi(optarg);
+			if (ret < EROFS_MSG_MIN || ret > EROFS_MSG_MAX) {
+				erofs_err("invalid debug level %d", ret);
 				return -EINVAL;
 			}
-			cfg.c_dbg_lvl = i;
+			cfg.c_dbg_lvl = ret;
 			break;
 		case 'p':
 			fsckcfg.print_comp_ratio = true;
@@ -71,6 +73,12 @@ static int erofsfsck_parse_options_cfg(int argc, char **argv)
 		case 2:
 			fsckcfg.check_decomp = true;
 			break;
+		case 3:
+			ret = blob_open_ro(optarg);
+			if (ret)
+				return ret;
+			++sbi.extra_devices;
+			break;
 		default:
 			return -EINVAL;
 		}
@@ -275,6 +283,7 @@ static int verify_compressed_inode(struct erofs_inode *inode)
 	struct erofs_map_blocks map = {
 		.index = UINT_MAX,
 	};
+	struct erofs_map_dev mdev;
 	int ret = 0;
 	u64 pchunk_len = 0;
 	erofs_off_t end = inode->i_size;
@@ -317,10 +326,21 @@ static int verify_compressed_inode(struct erofs_inode *inode)
 			BUG_ON(!buffer);
 		}
 
-		ret = dev_read(0, raw, map.m_pa, map.m_plen);
+		mdev = (struct erofs_map_dev) {
+			.m_deviceid = map.m_deviceid,
+			.m_pa = map.m_pa,
+		};
+		ret = erofs_map_dev(&sbi, &mdev);
+		if (ret) {
+			erofs_err("failed to map device of m_pa %" PRIu64 ", m_deviceid %u @ nid %llu: %d",
+				  map.m_pa, map.m_deviceid, inode->nid | 0ULL, ret);
+			goto out;
+		}
+
+		ret = dev_read(mdev.m_deviceid, raw, mdev.m_pa, map.m_plen);
 		if (ret < 0) {
 			erofs_err("failed to read compressed data of m_pa %" PRIu64 ", m_plen %" PRIu64 " @ nid %llu: %d",
-				  map.m_pa, map.m_plen, inode->nid | 0ULL, ret);
+				  mdev.m_pa, map.m_plen, inode->nid | 0ULL, ret);
 			goto out;
 		}
 
@@ -336,7 +356,7 @@ static int verify_compressed_inode(struct erofs_inode *inode)
 
 		if (ret < 0) {
 			erofs_err("failed to decompress data of m_pa %" PRIu64 ", m_plen %" PRIu64 " @ nid %llu: %d",
-				  map.m_pa, map.m_plen, inode->nid | 0ULL, ret);
+				  mdev.m_pa, map.m_plen, inode->nid | 0ULL, ret);
 			goto out;
 		}
 	}
@@ -558,12 +578,12 @@ int main(int argc, char **argv)
 	err = erofs_read_superblock();
 	if (err) {
 		erofs_err("failed to read superblock");
-		goto exit;
+		goto exit_dev_close;
 	}
 
 	if (erofs_sb_has_sb_chksum() && erofs_check_sb_chksum()) {
 		erofs_err("failed to verify superblock checksum");
-		goto exit;
+		goto exit_dev_close;
 	}
 
 	erofs_check_inode(sbi.root_nid, sbi.root_nid);
@@ -582,7 +602,10 @@ int main(int argc, char **argv)
 		}
 	}
 
+exit_dev_close:
+	dev_close();
 exit:
+	blob_closeall();
 	erofs_exit_configure();
 	return err ? 1 : 0;
 }
-- 
2.24.4



More information about the Linux-erofs mailing list