@@ -91,12 +91,12 @@ static struct Command commands[] = {
"filesystem df", "<path>\n"
"Show space usage information for a mount point\n."
},
- { do_balance, 1,
- "filesystem balance", "<path>\n"
+ { do_balance, -1,
+ "filesystem balance", "[-w|--wait] <path>\n"
"Balance the chunks across the device."
},
- { do_balance, 1,
- "balance start", "<path>\n"
+ { do_balance, -1,
+ "balance start", "[-w|--wait] <path>\n"
"Synonym for \"btrfs filesystem balance\"."
},
{ do_balance_progress, -1,
@@ -754,12 +754,41 @@ int do_add_volume(int nargs, char **args)
}
+const struct option balance_options[] = {
+ { "wait", 0, NULL, 'w' },
+ { NULL, 0, NULL, 0 }
+};
+
int do_balance(int argc, char **argv)
{
-
int fdmnt, ret=0;
+ int background = 1;
struct btrfs_ioctl_vol_args args;
- char *path = argv[1];
+ char *path;
+ int ttyfd;
+
+ optind = 1;
+ while(1) {
+ int c = getopt_long(argc, argv, "w", balance_options, NULL);
+ if (c < 0)
+ break;
+ switch(c) {
+ case 'w':
+ background = 0;
+ break;
+ default:
+ fprintf(stderr, "Invalid arguments for balance\n");
+ free(argv);
+ return 1;
+ }
+ }
+
+ if(optind >= argc) {
+ fprintf(stderr, "No filesystem path given for balance\n");
+ return 1;
+ }
+
+ path = argv[optind];
fdmnt = open_file_or_dir(path);
if (fdmnt < 0) {
@@ -767,6 +796,25 @@ int do_balance(int argc, char **argv)
return 12;
}
+ if (background) {
+ int pid = fork();
+ if (pid == 0) {
+ /* We're in the child, and can run in the background */
+ ttyfd = open("/dev/tty", O_RDWR);
+ if (ttyfd > 0)
+ ioctl(ttyfd, TIOCNOTTY, 0);
+ /* Fall through to the BTRFS_IOC_BALANCE ioctl */
+ } else if (pid > 0) {
+ /* We're in the parent, and the fork succeeded */
+ printf("Background balance started\n");
+ return 0;
+ } else {
+ /* We're in the parent, and the fork failed */
+ fprintf(stderr, "ERROR: can't start background process -- %s\n",
+ strerror(errno));
+ }
+ }
+
memset(&args, 0, sizeof(args));
ret = ioctl(fdmnt, BTRFS_IOC_BALANCE, &args);
close(fdmnt);
@@ -21,11 +21,11 @@ btrfs \- control a btrfs filesystem
.PP
\fBbtrfs\fP \fBfilesystem resize\fP\fI [+/\-]<size>[gkm]|max <filesystem>\fP
.PP
-\fBbtrfs\fP \fBfilesystem balance\fP\fI <path> \fP
+\fBbtrfs\fP \fBfilesystem balance\fP [\fB-w\fP|\fB--wait\fP] \fI<path>\fP
.PP
\fBbtrfs\fP \fBdevice scan\fP\fI [<device> [<device>..]]\fP
.PP
-\fBbtrfs\fP \fBbalance start\fP\fI <path> \fP
+\fBbtrfs\fP \fBbalance start\fP [\fB-w\fP|\fB--wait\fP] \fI<path>\fP
.PP
\fBbtrfs\fP \fBbalance progress\fP [\fB-m\fP|\fB--monitor\fP] \fI<path>\fP
.PP
@@ -149,11 +149,13 @@ Show the btrfs filesystem with some additional info. If no UUID or label is
passed, \fBbtrfs\fR show info of all the btrfs filesystem.
.TP
-\fBbalance start\fR \fI<path>\fR
+\fBdevice balance\fR [\fB-w\fP|\fB--wait\fP] \fI<path>\fR
.TP
-\fBfilesystem balance\fR \fI<path>\fR
-Balance the chunks of the filesystem identified by \fI<path>\fR
-across the devices.
+\fBbalance start\fR [\fB-w\fP|\fB--wait\fP] \fI<path>\fR
+
+Balance the chunks of the filesystem identified by \fI<path>\fR across
+the devices. The process runs in the background. Use \fB--wait\fP to
+wait in the foreground for completion of the balance.
.TP
\fBdevice add\fR\fI <dev> [<dev>..] <path>\fR
This patch makes a balance operation fork and detach from the current terminal, to run the userspace side of the balance in the background. Introduce a --wait switch so that a synchronous balance can be done if the user requires. Signed-off-by: Hugo Mills <hugo@carfax.org.uk> --- btrfs.c | 8 ++++---- btrfs_cmds.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++-- man/btrfs.8.in | 14 ++++++++------ 3 files changed, 62 insertions(+), 12 deletions(-)