@@ -69,7 +69,7 @@ resume [-BdqrR] <path>|<device>
.. _man-scrub-start:
-start [-BdrRf] <path>|<device>
+start [-BdrRft] <path>|<device>
Start a scrub on all devices of the mounted filesystem identified by
*path* or on a single *device*. If a scrub is already running, the new
one will not start. A device of an unmounted filesystem cannot be
@@ -96,6 +96,13 @@ start [-BdrRf] <path>|<device>
can avoid writes from scrub.
-R
raw print mode, print full data instead of summary
+ -t <throughput_limit>
+ set the scrub throughput limit for each device, acts the same as
+ ``btrfs scrub limit -a -l <throughput_limit>``.
+
+ The value is bytes per second, and accept the usual KMGT prefixes.
+ After the scrub is finished, the throughput limit will be reset to
+ zero (aka, no limit).
-f
force starting new scrub even if a scrub is already running,
this can useful when scrub status file is damaged and reports a
@@ -1265,11 +1265,12 @@ static int scrub_start(const struct cmd_struct *cmd, int argc, char **argv,
struct scrub_progress_cycle spc;
pthread_mutex_t spc_write_mutex = PTHREAD_MUTEX_INITIALIZER;
void *terr;
+ u64 throughput = 0;
u64 devid;
bool force = false;
bool nothing_to_resume = false;
- while ((c = getopt(argc, argv, "BdqrRc:n:f")) != -1) {
+ while ((c = getopt(argc, argv, "BdqrRc:n:ft")) != -1) {
switch (c) {
case 'B':
do_background = false;
@@ -1291,6 +1292,9 @@ static int scrub_start(const struct cmd_struct *cmd, int argc, char **argv,
case 'c':
ioprio_class = (int)strtol(optarg, NULL, 10);
break;
+ case 't':
+ throughput = arg_strtou64_with_suffix(optarg);
+ break;
case 'n':
ioprio_classdata = (int)strtol(optarg, NULL, 10);
break;
@@ -1389,6 +1393,12 @@ static int scrub_start(const struct cmd_struct *cmd, int argc, char **argv,
for (i = 0; i < fi_args.num_devices; ++i) {
devid = di_args[i].devid;
+ ret = write_scrub_device_limit(fdmnt, devid, throughput);
+ if (ret < 0) {
+ errno = -ret;
+ warning("failed to set scrub throughput limit on devid %llu: %m",
+ devid);
+ }
ret = pthread_mutex_init(&sp[i].progress_mutex, NULL);
if (ret) {
errno = ret;
@@ -1568,6 +1578,16 @@ static int scrub_start(const struct cmd_struct *cmd, int argc, char **argv,
err = 0;
for (i = 0; i < fi_args.num_devices; ++i) {
+ /* We have set the limit, now reset it to 0. */
+ if (throughput) {
+ ret = write_scrub_device_limit(fdmnt, di_args[i].devid, 0);
+ if (ret < 0) {
+ errno = -ret;
+ warning("failed to reset scrub throughput limit on devid %llu: %m",
+ di_args[i].devid);
+ }
+ }
+
if (sp[i].skip)
continue;
devid = di_args[i].devid;
@@ -1713,6 +1733,7 @@ static const char * const cmd_scrub_start_usage[] = {
OPTLINE("-c", "set ioprio class (see ionice(1) manpage)"),
OPTLINE("-n", "set ioprio classdata (see ionice(1) manpage)"),
OPTLINE("-f", "force starting new scrub even if a scrub is already running this is useful when scrub stats record file is damaged"),
+ OPTLINE("-t", "set the throughput limit for each device"),
OPTLINE("-q", "deprecated, alias for global -q option"),
HELPINFO_INSERT_GLOBALS,
HELPINFO_INSERT_QUIET,
I know there is already `btrfs scrub limit` command to set the limit, but a lot of users are not aware of that command. Thus adding a new option `-t <throughput_limit>` to `btrfs scrub start`. This has some extra behavior compared to `btrfs scrub limit`: - Only set the value for the involved scrub device(s) If it's a full fs scrub, it will be the same as `btrfs scrub limit -a -l <value>`. If it's a single device, it will bt the same as `btrfs scrub limit -d <devid> -l <value>`. - Automatically reset the limit after scrub is finished - It only needs one single command line to set the limit Issue: #943 Signed-off-by: Qu Wenruo <wqu@suse.com> --- RFC: I'm not sure if this is really needed since we already have `btrfs scrub limit`. Involved tools like btrfs-maintenance scripts should have such support, but to my surprise, David introduced the `btrfs scrub limit` but not adding any support to btrfs-maintenance. --- Documentation/btrfs-scrub.rst | 9 ++++++++- cmds/scrub.c | 23 ++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-)