From 45fda3c03c013b3596a1a9bbdf5514050f2e4812cf1a7280e60577686e3660e4 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Tue, 1 Sep 2015 09:16:29 +0000 Subject: [PATCH] Accepting request 328269 from home:dsterba:branches:filesystems - add warning before full balance starts (bsc#940467, fate#319317) Patch will go upstream soon. OBS-URL: https://build.opensuse.org/request/show/328269 OBS-URL: https://build.opensuse.org/package/show/filesystems/btrfsprogs?expand=0&rev=208 --- 2000-btrfs-full-balance-warning.diff | 215 +++++++++++++++++++++++++++ btrfsprogs.changes | 7 + btrfsprogs.spec | 2 + 3 files changed, 224 insertions(+) create mode 100644 2000-btrfs-full-balance-warning.diff diff --git a/2000-btrfs-full-balance-warning.diff b/2000-btrfs-full-balance-warning.diff new file mode 100644 index 0000000..45835fe --- /dev/null +++ b/2000-btrfs-full-balance-warning.diff @@ -0,0 +1,215 @@ +diff --git a/Documentation/btrfs-balance.asciidoc b/Documentation/btrfs-balance.asciidoc +index 6d2fd0c36086..12c2a2dc9fbd 100644 +--- a/Documentation/btrfs-balance.asciidoc ++++ b/Documentation/btrfs-balance.asciidoc +@@ -45,6 +45,12 @@ If filter list is not given balance all chunks of that type. + In case none of the -d, -m or -s options is + given balance all chunks in a filesystem. + + ++NOTE: the balance command without filters will basically rewrite everything ++int the filesystem. The run time is potentially very long, depending on the ++filesystem size. To prevent starting a full balance by accident, the user is ++warned and has a few seconds to cancel the operation before it starts. The ++warning and delay can be skipped with '--full-balance' option. +++ + `Options` + + + -d[]:::: +@@ -57,6 +63,8 @@ act on system chunks (only under -f). See `FILTERS` section for details about :: + Show status of running or paused balance. +diff --git a/cmds-balance.c b/cmds-balance.c +index 9af218bbfa51..bab0e053c8bc 100644 +--- a/cmds-balance.c ++++ b/cmds-balance.c +@@ -298,8 +298,13 @@ static int do_balance_v1(int fd) + return ret; + } + ++enum { ++ BALANCE_START_FILTERS = 1 << 0, ++ BALANCE_START_NOWARN = 1 << 1 ++}; ++ + static int do_balance(const char *path, struct btrfs_ioctl_balance_args *args, +- int nofilters) ++ unsigned flags) + { + int fd; + int ret; +@@ -312,6 +317,24 @@ static int do_balance(const char *path, struct btrfs_ioctl_balance_args *args, + return 1; + } + ++ if (!(flags & BALANCE_START_FILTERS) && !(flags & BALANCE_START_NOWARN)) { ++ int delay = 10; ++ ++ printf("WARNING:\n\n"); ++ printf("\tFull balance without filters requested. This operation is very\n"); ++ printf("\tintense and takes potentially very long. It is recommended to\n"); ++ printf("\tuse the balance filters to narrow down the balanced data.\n"); ++ printf("\tUse 'btrfs balance start --full-balance' option to skip this\n"); ++ printf("\twarning. The operation printf will start in %d seconds.\n", delay); ++ printf("\tUse Ctrl-C to stop it.\n"); ++ while (delay) { ++ sleep(1); ++ printf("%2d", delay--); ++ fflush(stdout); ++ } ++ printf("\nStarting balance without any filters.\n"); ++ } ++ + ret = ioctl(fd, BTRFS_IOC_BALANCE_V2, args); + e = errno; + +@@ -321,7 +344,7 @@ static int do_balance(const char *path, struct btrfs_ioctl_balance_args *args, + * old one. But, the old one doesn't know any filters, so + * don't fall back if they tried to use the fancy new things + */ +- if (e == ENOTTY && nofilters) { ++ if (e == ENOTTY && !(flags & BALANCE_START_FILTERS)) { + ret = do_balance_v1(fd); + if (ret == 0) + goto out; +@@ -361,13 +384,16 @@ static const char * const cmd_balance_start_usage[] = { + "passed all filters in a comma-separated list of filters for a", + "particular chunk type. If filter list is not given balance all", + "chunks of that type. In case none of the -d, -m or -s options is", +- "given balance all chunks in a filesystem.", ++ "given balance all chunks in a filesystem. This is potentially", ++ "long operation and the user is warned before this start, with", ++ "a delay to stop it.", + "", + "-d[filters] act on data chunks", + "-m[filters] act on metadata chunks", + "-s[filters] act on system chunks (only under -f)", + "-v be verbose", + "-f force reducing of metadata integrity", ++ "--full-balance do not print warning and do not delay start", + NULL + }; + +@@ -378,19 +404,22 @@ static int cmd_balance_start(int argc, char **argv) + &args.meta, NULL }; + int force = 0; + int verbose = 0; +- int nofilters = 1; ++ unsigned start_flags = 0; + int i; + + memset(&args, 0, sizeof(args)); + + optind = 1; + while (1) { ++ enum { GETOPT_VAL_FULL_BALANCE = 256 }; + static const struct option longopts[] = { + { "data", optional_argument, NULL, 'd'}, + { "metadata", optional_argument, NULL, 'm' }, + { "system", optional_argument, NULL, 's' }, + { "force", no_argument, NULL, 'f' }, + { "verbose", no_argument, NULL, 'v' }, ++ { "full-balance", no_argument, NULL, ++ GETOPT_VAL_FULL_BALANCE }, + { NULL, 0, NULL, 0 } + }; + +@@ -400,21 +429,21 @@ static int cmd_balance_start(int argc, char **argv) + + switch (opt) { + case 'd': +- nofilters = 0; ++ start_flags |= BALANCE_START_FILTERS; + args.flags |= BTRFS_BALANCE_DATA; + + if (parse_filters(optarg, &args.data)) + return 1; + break; + case 's': +- nofilters = 0; ++ start_flags |= BALANCE_START_FILTERS; + args.flags |= BTRFS_BALANCE_SYSTEM; + + if (parse_filters(optarg, &args.sys)) + return 1; + break; + case 'm': +- nofilters = 0; ++ start_flags |= BALANCE_START_FILTERS; + args.flags |= BTRFS_BALANCE_METADATA; + + if (parse_filters(optarg, &args.meta)) +@@ -426,6 +455,9 @@ static int cmd_balance_start(int argc, char **argv) + case 'v': + verbose = 1; + break; ++ case GETOPT_VAL_FULL_BALANCE: ++ start_flags |= BALANCE_START_NOWARN; ++ break; + default: + usage(cmd_balance_start_usage); + } +@@ -451,7 +483,7 @@ static int cmd_balance_start(int argc, char **argv) + sizeof(struct btrfs_balance_args)); + } + +- if (nofilters) { ++ if (!(start_flags & BALANCE_START_FILTERS)) { + /* relocate everything - no filters */ + args.flags |= BTRFS_BALANCE_TYPE_MASK; + } +@@ -481,7 +513,7 @@ static int cmd_balance_start(int argc, char **argv) + if (verbose) + dump_ioctl_balance_args(&args); + +- return do_balance(argv[optind], &args, nofilters); ++ return do_balance(argv[optind], &args, start_flags); + } + + static const char * const cmd_balance_pause_usage[] = { +@@ -723,6 +755,16 @@ static int cmd_balance_status(int argc, char **argv) + return 1; + } + ++static int cmd_balance_full(int argc, char **argv) ++{ ++ struct btrfs_ioctl_balance_args args; ++ ++ memset(&args, 0, sizeof(args)); ++ args.flags |= BTRFS_BALANCE_TYPE_MASK; ++ ++ return do_balance(argv[1], &args, BALANCE_START_NOWARN); ++} ++ + static const char balance_cmd_group_info[] = + "balance data accross devices, or change block groups using filters"; + +@@ -733,20 +775,21 @@ const struct cmd_group balance_cmd_group = { + { "cancel", cmd_balance_cancel, cmd_balance_cancel_usage, NULL, 0 }, + { "resume", cmd_balance_resume, cmd_balance_resume_usage, NULL, 0 }, + { "status", cmd_balance_status, cmd_balance_status_usage, NULL, 0 }, ++ { "--full-balance", cmd_balance_full, NULL, NULL, 1 }, + NULL_CMD_STRUCT + } + }; + + int cmd_balance(int argc, char **argv) + { +- if (argc == 2) { ++ if (argc == 2 && strcmp("start", argv[1]) != 0) { + /* old 'btrfs filesystem balance ' syntax */ + struct btrfs_ioctl_balance_args args; + + memset(&args, 0, sizeof(args)); + args.flags |= BTRFS_BALANCE_TYPE_MASK; + +- return do_balance(argv[1], &args, 1); ++ return do_balance(argv[1], &args, 0); + } + + return handle_command_group(&balance_cmd_group, argc, argv); diff --git a/btrfsprogs.changes b/btrfsprogs.changes index c7d777c..ff76da5 100644 --- a/btrfsprogs.changes +++ b/btrfsprogs.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Sep 1 00:00:00 CEST 2015 - dsterba@suse.cz + +- add warning before full balance starts (bsc#940467, fate#319317) +- Added patches: + 2000-btrfs-full-balance-warning.diff + ------------------------------------------------------------------- Fri Jul 24 10:53:54 UTC 2015 - fdmanana@suse.com diff --git a/btrfsprogs.spec b/btrfsprogs.spec index 4b89c90..ce8d1eb 100644 --- a/btrfsprogs.spec +++ b/btrfsprogs.spec @@ -39,6 +39,7 @@ Patch2106: 2106-inspect-add-command-min-dev-size.patch Patch1000: local-version-override.patch Patch1001: fix-doc-build-on-SLE11SP3.diff +Patch1002: 2000-btrfs-full-balance-warning.diff BuildRequires: asciidoc BuildRequires: autoconf @@ -89,6 +90,7 @@ build applications to interface with btrfs. %patch2106 -p1 %patch1000 -p1 %patch1001 -p1 +%patch1002 -p1 %build ./autogen.sh