diff mbox series

[07/10] btrfs-progs: check: introduce --device option

Message ID 64679fafee4e8865de841c120444ff6b31189d78.1687943122.git.anand.jain@oracle.com (mailing list archive)
State New, archived
Headers show
Series btrfs-progs: check and tune: add device and noscan options | expand

Commit Message

Anand Jain June 28, 2023, 11:56 a.m. UTC
As of now, btrfs check only accepts one device from the command line and
then scans the system to find other parter devices if any.

However, this method mandates always accessing the file raw image as a
loop device.

This patch modifies btrfs check to accept other devices or reg-files from
the command line using an option --device and scans/registers them.

    For example:

            btrfs check --device /tdev/td1,/tdev/td2 /tdev/td3
      or
            btrfs check --device /tdev/td1 --device /tdev/td2 /tdev/td3

Signed-off-by: Anand Jain <anand.jain@oracle.com>
---
 check/main.c | 41 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 39 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/check/main.c b/check/main.c
index 2f4fa5ada339..7eb57f10aded 100644
--- a/check/main.c
+++ b/check/main.c
@@ -51,6 +51,7 @@ 
 #include "common/messages.h"
 #include "common/task-utils.h"
 #include "common/device-utils.h"
+#include "common/device-scan.h"
 #include "common/utils.h"
 #include "common/rbtree-utils.h"
 #include "common/help.h"
@@ -9953,6 +9954,7 @@  static const char * const cmd_check_usage[] = {
 	OPTLINE("-b|--backup", "use the first valid backup root copy"),
 	OPTLINE("-r|--tree-root <bytenr>", "use the given bytenr for the tree root"),
 	OPTLINE("--chunk-root <bytenr>", "use the given bytenr for the chunk tree root"),
+	OPTLINE("--device <device>", "use the given device or regular-file"),
 	"",
 	"Operation modes:",
 	OPTLINE("--readonly", "run in read-only mode (default)"),
@@ -9989,6 +9991,8 @@  static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv)
 	u64 tree_root_bytenr = 0;
 	u64 chunk_root_bytenr = 0;
 	char uuidbuf[BTRFS_UUID_UNPARSED_SIZE];
+	char **argv_devices = NULL;
+	int argc_devices = 0;
 	int ret = 0;
 	int err = 0;
 	u64 num;
@@ -10010,7 +10014,8 @@  static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv)
 			GETOPT_VAL_INIT_EXTENT, GETOPT_VAL_CHECK_CSUM,
 			GETOPT_VAL_READONLY, GETOPT_VAL_CHUNK_TREE,
 			GETOPT_VAL_MODE, GETOPT_VAL_CLEAR_SPACE_CACHE,
-			GETOPT_VAL_CLEAR_INO_CACHE, GETOPT_VAL_FORCE };
+			GETOPT_VAL_CLEAR_INO_CACHE, GETOPT_VAL_FORCE,
+			GETOPT_VAL_DEVICE };
 		static const struct option long_options[] = {
 			{ "super", required_argument, NULL, 's' },
 			{ "repair", no_argument, NULL, GETOPT_VAL_REPAIR },
@@ -10035,6 +10040,7 @@  static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv)
 			{ "clear-ino-cache", no_argument , NULL,
 				GETOPT_VAL_CLEAR_INO_CACHE},
 			{ "force", no_argument, NULL, GETOPT_VAL_FORCE },
+			{ "device", required_argument, NULL, GETOPT_VAL_DEVICE },
 			{ NULL, 0, NULL, 0}
 		};
 
@@ -10126,6 +10132,22 @@  static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv)
 			case GETOPT_VAL_FORCE:
 				force = 1;
 				break;
+			case GETOPT_VAL_DEVICE:
+				if (!argv_devices) {
+					argv_devices = malloc(sizeof(char *));
+					if (!argv_devices) {
+						error("memory alloc failed");
+						exit(1);
+					}
+				}
+
+				if (!array_append(argv_devices, optarg,
+						  &argc_devices)) {
+					error("memory alloc failed");
+					free(argv_devices);
+					exit(1);
+				}
+				break;
 		}
 	}
 
@@ -10200,6 +10222,19 @@  static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv)
 		ctree_flags &= ~OPEN_CTREE_EXCLUSIVE;
 	}
 
+	/*
+	 * check_mounted_where() with noscan == true frees the scanned devices
+	 * scan the command line provided device list now.
+	 */
+	if (argv_devices) {
+		ret = btrfs_scan_argv_devices(0, argc_devices, argv_devices);
+		if (ret) {
+			ret = -EIO;
+			err |= !!ret;
+			goto free_out;
+		}
+	}
+
 	/* only allow partial opening under repair mode */
 	if (opt_check_repair)
 		ctree_flags |= OPEN_CTREE_PARTIAL;
@@ -10214,7 +10249,7 @@  static int cmd_check(const struct cmd_struct *cmd, int argc, char **argv)
 		error("cannot open file system");
 		ret = -EIO;
 		err |= !!ret;
-		goto err_out;
+		goto free_out;
 	}
 
 	root = gfs_info->fs_root;
@@ -10560,6 +10595,8 @@  out:
 	free_root_recs_tree(&root_cache);
 close_out:
 	close_ctree(root);
+free_out:
+	free_array(argv_devices, argc_devices);
 err_out:
 	if (g_task_ctx.progress_enabled)
 		task_deinit(g_task_ctx.info);