@@ -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);
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(-)