static int do_balance(const char *path, struct btrfs_ioctl_balance_args *args, int nofilters) { int fd; int ret; int e; DIR *dirstream = NULL; fd = open_file_or_dir(path, &dirstream); if (fd < 0) { fprintf(stderr, "ERROR: can't access '%s'\n", path); return 1; } ret = ioctl(fd, BTRFS_IOC_BALANCE_V2, args); e = errno; if (ret < 0) { /* * older kernels don't have the new balance ioctl, try the * 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) { ret = do_balance_v1(fd); if (ret == 0) goto out; e = errno; } if (e == ECANCELED) { if (args->state & BTRFS_BALANCE_STATE_PAUSE_REQ) fprintf(stderr, "balance paused by user\n"); if (args->state & BTRFS_BALANCE_STATE_CANCEL_REQ) fprintf(stderr, "balance canceled by user\n"); ret = 0; } else { fprintf(stderr, "ERROR: error during balancing '%s' " "- %s\n", path, strerror(e)); if (e != EINPROGRESS) fprintf(stderr, "There may be more info in " "syslog - try dmesg | tail\n"); ret = 1; } } else { printf("Done, had to relocate %llu out of %llu chunks\n", (unsigned long long)args->stat.completed, (unsigned long long)args->stat.considered); ret = 0; } out: close_file_or_dir(fd, dirstream); return ret; }
static int do_balance(const char *path, struct btrfs_ioctl_balance_args *args, unsigned flags) { int fd; int ret; int e; DIR *dirstream = NULL; fd = btrfs_open_dir(path, &dirstream, 1); if (fd < 0) 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 will start in %d seconds.\n", delay); printf("\tUse Ctrl-C to stop it.\n"); while (delay) { printf("%2d", delay--); fflush(stdout); sleep(1); } printf("\nStarting balance without any filters.\n"); } ret = ioctl(fd, BTRFS_IOC_BALANCE_V2, args); e = errno; if (ret < 0) { /* * older kernels don't have the new balance ioctl, try the * 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 && !(flags & BALANCE_START_FILTERS)) { ret = do_balance_v1(fd); if (ret == 0) goto out; e = errno; } if (e == ECANCELED) { if (args->state & BTRFS_BALANCE_STATE_PAUSE_REQ) fprintf(stderr, "balance paused by user\n"); if (args->state & BTRFS_BALANCE_STATE_CANCEL_REQ) fprintf(stderr, "balance canceled by user\n"); ret = 0; } else { error("error during balancing '%s': %s", path, strerror(e)); if (e != EINPROGRESS) fprintf(stderr, "There may be more info in syslog - try dmesg | tail\n"); ret = 1; } } else { printf("Done, had to relocate %llu out of %llu chunks\n", (unsigned long long)args->stat.completed, (unsigned long long)args->stat.considered); ret = 0; } out: close_file_or_dir(fd, dirstream); return ret; }