btrfs-progs: check: adjust command line options for the low-memory mode

Change the single-purpose option --low-memory to a generic option that
takes the mode. Currently supported are the original mode and the
low-memory in the same way.

Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
David Sterba 2016-08-17 19:33:24 +02:00
parent bfecd8bd6a
commit 87c1bd13c1
2 changed files with 50 additions and 14 deletions

View File

@ -93,11 +93,18 @@ build the extent tree from scratch
+
NOTE: Do not use unless you know what you're doing.
--low-memory::
check fs in low memory usage mode(experimental)
May takes longer time than normal check.
--mode=MODE::
select mode of operation regarding memory and IO
+
NOTE: Doesn't work with '--repair' option yet.
The 'MODE' can be one of 'original' and 'lowmem'. The original mode is mostly
unoptimized regarding memory consumpption and can lead to out-of-memory
conditions on large filesystems. The possible workaround is to export the block
device over network to a machine with enough memory. The low memory mode is
supposed to address the memory consumption, at the cost of increased IO when it
needs to re-read blocks when needed. This may increase run time.
NOTE: 'lowmem' mode does not work with '--repair' yet, and is still considered
experimental.
EXIT STATUS
-----------

View File

@ -70,11 +70,19 @@ static LIST_HEAD(delete_items);
static int no_holes = 0;
static int init_extent_tree = 0;
static int check_data_csum = 0;
static int low_memory = 0;
static struct btrfs_fs_info *global_info;
static struct task_ctx ctx = { 0 };
static struct cache_tree *roots_info_cache = NULL;
enum btrfs_check_mode {
CHECK_MODE_ORIGINAL,
CHECK_MODE_LOWMEM,
CHECK_MODE_UNKNOWN,
CHECK_MODE_DEFAULT = CHECK_MODE_ORIGINAL
};
static enum btrfs_check_mode check_mode = CHECK_MODE_DEFAULT;
struct extent_backref {
struct rb_node node;
unsigned int is_data:1;
@ -486,6 +494,18 @@ static int print_status_return(void *p)
return 0;
}
static enum btrfs_check_mode parse_check_mode(const char *str)
{
if (strcmp(str, "lowmem") == 0)
return CHECK_MODE_LOWMEM;
if (strcmp(str, "orig") == 0)
return CHECK_MODE_ORIGINAL;
if (strcmp(str, "original") == 0)
return CHECK_MODE_ORIGINAL;
return CHECK_MODE_UNKNOWN;
}
/* Compatible function to allow reuse of old codes */
static u64 first_extent_gap(struct rb_root *holes)
{
@ -11117,7 +11137,7 @@ const char * const cmd_check_usage[] = {
"Check structural integrity of a filesystem (unmounted).",
"Check structural integrity of an unmounted filesystem. Verify internal",
"trees' consistency and item connectivity. In the repair mode try to",
"fix the problems found.",
"fix the problems found. ",
"WARNING: the repair mode is considered dangerous",
"",
"-s|--super <superblock> use this superblock copy",
@ -11126,7 +11146,12 @@ const char * const cmd_check_usage[] = {
"--readonly run in read-only mode (default)",
"--init-csum-tree create a new CRC tree",
"--init-extent-tree create a new extent tree",
"--low-memory check in low memory usage mode(experimental)",
"--mode <MODE> select mode, allows to make some memory/IO",
" trade-offs, where MODE is one of:",
" original - read inodes and extents to memory (requires",
" more memory, does less IO)",
" lowmem - try to use less memory but read blocks again",
" when needed",
"--check-data-csum verify checksums of data blocks",
"-Q|--qgroup-report print a report on qgroup consistency",
"-E|--subvol-extents <subvolid>",
@ -11160,7 +11185,7 @@ int cmd_check(int argc, char **argv)
enum { GETOPT_VAL_REPAIR = 257, GETOPT_VAL_INIT_CSUM,
GETOPT_VAL_INIT_EXTENT, GETOPT_VAL_CHECK_CSUM,
GETOPT_VAL_READONLY, GETOPT_VAL_CHUNK_TREE,
GETOPT_VAL_LOW_MEMORY };
GETOPT_VAL_MODE };
static const struct option long_options[] = {
{ "super", required_argument, NULL, 's' },
{ "repair", no_argument, NULL, GETOPT_VAL_REPAIR },
@ -11178,8 +11203,8 @@ int cmd_check(int argc, char **argv)
{ "chunk-root", required_argument, NULL,
GETOPT_VAL_CHUNK_TREE },
{ "progress", no_argument, NULL, 'p' },
{ "low-memory", no_argument, NULL,
GETOPT_VAL_LOW_MEMORY },
{ "mode", required_argument, NULL,
GETOPT_VAL_MODE },
{ NULL, 0, NULL, 0}
};
@ -11244,8 +11269,12 @@ int cmd_check(int argc, char **argv)
case GETOPT_VAL_CHECK_CSUM:
check_data_csum = 1;
break;
case GETOPT_VAL_LOW_MEMORY:
low_memory = 1;
case GETOPT_VAL_MODE:
check_mode = parse_check_mode(optarg);
if (check_mode == CHECK_MODE_UNKNOWN) {
error("unknown mode: %s", optarg);
exit(1);
}
break;
}
}
@ -11267,7 +11296,7 @@ int cmd_check(int argc, char **argv)
/*
* Not supported yet
*/
if (repair && low_memory) {
if (repair && check_mode == CHECK_MODE_LOWMEM) {
error("Low memory mode doesn't support repair yet");
exit(1);
}
@ -11395,7 +11424,7 @@ int cmd_check(int argc, char **argv)
if (!ctx.progress_enabled)
fprintf(stderr, "checking extents\n");
if (low_memory)
if (check_mode == CHECK_MODE_LOWMEM)
ret = check_chunks_and_extents_v2(root);
else
ret = check_chunks_and_extents(root);