summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds-scrub.c40
-rw-r--r--man/btrfs.8.in22
2 files changed, 55 insertions, 7 deletions
diff --git a/cmds-scrub.c b/cmds-scrub.c
index f06eb20d..59223615 100644
--- a/cmds-scrub.c
+++ b/cmds-scrub.c
@@ -24,6 +24,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <sys/syscall.h>
#include <poll.h>
#include <sys/file.h>
#include <uuid/uuid.h>
@@ -60,6 +61,15 @@ struct scrub_stats {
u64 canceled;
};
+/* TBD: replace with #include "linux/ioprio.h" in some years */
+#if !defined (IOPRIO_H)
+#define IOPRIO_WHO_PROCESS 1
+#define IOPRIO_CLASS_SHIFT 13
+#define IOPRIO_PRIO_VALUE(class, data) \
+ (((class) << IOPRIO_CLASS_SHIFT) | (data))
+#define IOPRIO_CLASS_IDLE 3
+#endif
+
struct scrub_progress {
struct btrfs_ioctl_scrub_args scrub_args;
int fd;
@@ -69,6 +79,8 @@ struct scrub_progress {
struct scrub_file_record *resumed;
int ioctl_errno;
pthread_mutex_t progress_mutex;
+ int ioprio_class;
+ int ioprio_classdata;
};
struct scrub_file_record {
@@ -813,6 +825,14 @@ static void *scrub_one_dev(void *ctx)
sp->stats.duration = 0;
sp->stats.finished = 0;
+ ret = syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, 0,
+ IOPRIO_PRIO_VALUE(sp->ioprio_class,
+ sp->ioprio_classdata));
+ if (ret)
+ fprintf(stderr,
+ "WARNING: setting ioprio failed: %s (ignored).\n",
+ strerror(errno));
+
ret = ioctl(sp->fd, BTRFS_IOC_SCRUB, &sp->scrub_args);
gettimeofday(&tv, NULL);
sp->ret = ret;
@@ -1029,6 +1049,8 @@ static int scrub_start(int argc, char **argv, int resume)
int do_record = 1;
int readonly = 0;
int do_stats_per_dev = 0;
+ int ioprio_class = IOPRIO_CLASS_IDLE;
+ int ioprio_classdata = 0;
int n_start = 0;
int n_skip = 0;
int n_resume = 0;
@@ -1054,7 +1076,7 @@ static int scrub_start(int argc, char **argv, int resume)
u64 devid;
optind = 1;
- while ((c = getopt(argc, argv, "BdqrR")) != -1) {
+ while ((c = getopt(argc, argv, "BdqrRc:n:")) != -1) {
switch (c) {
case 'B':
do_background = 0;
@@ -1073,6 +1095,12 @@ static int scrub_start(int argc, char **argv, int resume)
case 'R':
print_raw = 1;
break;
+ case 'c':
+ ioprio_class = (int)strtol(optarg, NULL, 10);
+ break;
+ case 'n':
+ ioprio_classdata = (int)strtol(optarg, NULL, 10);
+ break;
case '?':
default:
usage(resume ? cmd_scrub_resume_usage :
@@ -1182,6 +1210,8 @@ static int scrub_start(int argc, char **argv, int resume)
sp[i].skip = 0;
sp[i].scrub_args.end = (u64)-1ll;
sp[i].scrub_args.flags = readonly ? BTRFS_SCRUB_READONLY : 0;
+ sp[i].ioprio_class = ioprio_class;
+ sp[i].ioprio_classdata = ioprio_classdata;
}
if (!n_start && !n_resume) {
@@ -1435,13 +1465,15 @@ out:
}
static const char * const cmd_scrub_start_usage[] = {
- "btrfs scrub start [-Bdqr] <path>|<device>",
+ "btrfs scrub start Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n",
"Start a new scrub",
"",
"-B do not background",
"-d stats per device (-B only)",
"-q be quiet",
"-r read only mode",
+ "-c set ioprio class (see ionice(1) manpage)",
+ "-n set ioprio classdata (see ionice(1) manpage)",
NULL
};
@@ -1494,13 +1526,15 @@ out:
}
static const char * const cmd_scrub_resume_usage[] = {
- "btrfs scrub resume [-Bdqr] <path>|<device>",
+ "btrfs scrub resume [-Bdqr] [-c ioprio_class -n ioprio_classdata] <path>|<device>\n",
"Resume previously canceled or interrupted scrub",
"",
"-B do not background",
"-d stats per device (-B only)",
"-q be quiet",
"-r read only mode",
+ "-c set ioprio class (see ionice(1) manpage)",
+ "-n set ioprio classdata (see ionice(1) manpage)",
NULL
};
diff --git a/man/btrfs.8.in b/man/btrfs.8.in
index 94f4ffea..08e5fd79 100644
--- a/man/btrfs.8.in
+++ b/man/btrfs.8.in
@@ -47,11 +47,11 @@ btrfs \- control a btrfs filesystem
.PP
\fBbtrfs\fP \fBreplace cancel\fP \fI<path>\fP
.PP
-\fBbtrfs\fP \fBscrub start\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
+\fBbtrfs\fP \fBscrub start\fP [-Bdqru] [-c ioprio_class -n ioprio_classdata] {\fI<path>\fP|\fI<device>\fP}
.PP
\fBbtrfs\fP \fBscrub cancel\fP {\fI<path>\fP|\fI<device>\fP}
.PP
-\fBbtrfs\fP \fBscrub resume\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
+\fBbtrfs\fP \fBscrub resume\fP [-Bdqru] [-c ioprio_class -n ioprio_classdata] {\fI<path>\fP|\fI<device>\fP}
.PP
\fBbtrfs\fP \fBscrub status\fP [-d] {\fI<path>\fP|\fI<device>\fP}
.PP
@@ -355,11 +355,16 @@ Cancel a running device replace operation.
.TP
\fBscrub start\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
+\fBscrub start\fP [-Bdqru] [-c ioprio_class -n ioprio_classdata] {\fI<path>\fP|\fI<device>\fP}
Start a scrub on all devices of the filesystem identified by \fI<path>\fR or on
a single \fI<device>\fR. Without options, scrub is started as a background
process. Progress can be obtained with the \fBscrub status\fR command. Scrubbing
involves reading all data from all disks and verifying checksums. Errors are
corrected along the way if possible.
+.IP
+The default IO priority of scrub is the idle class. The priority can be configured similar to the
+.BR ionice (1)
+syntax.
.RS
\fIOptions\fR
@@ -373,6 +378,14 @@ Quiet. Omit error messages and statistics.
Read only mode. Do not attempt to correct anything.
.IP -u 5
Scrub unused space as well. (NOT IMPLEMENTED)
+.IP -c 5
+Set IO priority class (see
+.BR ionice (1)
+manpage).
+.IP -n 5
+Set IO priority classdata (see
+.BR ionice (1)
+manpage).
.RE
.TP
@@ -384,7 +397,7 @@ If a \fI<device>\fR is given, the corresponding filesystem is found and
\fBscrub cancel\fP behaves as if it was called on that filesystem.
.TP
-\fBscrub resume\fP [-Bdqru] {\fI<path>\fP|\fI<device>\fP}
+\fBscrub resume\fP [-Bdqru] [-c ioprio_class -n ioprio_classdata] {\fI<path>\fP|\fI<device>\fP}
Resume a canceled or interrupted scrub cycle on the filesystem identified by
\fI<path>\fR or on a given \fI<device>\fR. Does not start a new scrub if the
last scrub finished successfully.
@@ -446,4 +459,5 @@ and not suitable for any uses other than benchmarking and review.
Please refer to the btrfs wiki http://btrfs.wiki.kernel.org for
further details.
.SH SEE ALSO
-.BR mkfs.btrfs (8)
+.BR mkfs.btrfs (8),
+.BR ionice (1)