Btrfs-progs: add 'balance' command group infrastructure
[platform/upstream/btrfs-progs.git] / cmds-balance.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public
4  * License v2 as published by the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9  * General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public
12  * License along with this program; if not, write to the
13  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
14  * Boston, MA 021110-1307, USA.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <sys/ioctl.h>
22 #include <errno.h>
23
24 #include "kerncompat.h"
25 #include "ctree.h"
26 #include "ioctl.h"
27 #include "volumes.h"
28
29 #include "commands.h"
30
31 static const char balance_cmd_group_usage[] =
32         "btrfs [filesystem] balance [<command>] [options] <path>";
33
34 static const char balance_cmd_group_info[] =
35         "'btrfs filesystem balance' command is deprecated, please use\n"
36         "'btrfs balance start' command instead.";
37
38 static int do_balance(const char *path, struct btrfs_ioctl_balance_args *args)
39 {
40         int fd;
41         int ret;
42         int e;
43
44         fd = open_file_or_dir(path);
45         if (fd < 0) {
46                 fprintf(stderr, "ERROR: can't access to '%s'\n", path);
47                 return 12;
48         }
49
50         ret = ioctl(fd, BTRFS_IOC_BALANCE_V2, args);
51         e = errno;
52         close(fd);
53
54         if (ret < 0) {
55                 if (e == ECANCELED) {
56                         if (args->state & BTRFS_BALANCE_STATE_PAUSE_REQ)
57                                 fprintf(stderr, "balance paused by user\n");
58                         if (args->state & BTRFS_BALANCE_STATE_CANCEL_REQ)
59                                 fprintf(stderr, "balance canceled by user\n");
60                 } else {
61                         fprintf(stderr, "ERROR: error during balancing '%s' "
62                                 "- %s\n", path, strerror(e));
63                         if (e != EINPROGRESS)
64                                 fprintf(stderr, "There may be more info in "
65                                         "syslog - try dmesg | tail\n");
66                         return 19;
67                 }
68         } else {
69                 printf("Done, had to relocate %llu out of %llu chunks\n",
70                        (unsigned long long)args->stat.completed,
71                        (unsigned long long)args->stat.considered);
72         }
73
74         return 0;
75 }
76
77 const struct cmd_group balance_cmd_group = {
78         balance_cmd_group_usage, balance_cmd_group_info, {
79                 { 0, 0, 0, 0, 0 }
80         }
81 };
82
83 int cmd_balance(int argc, char **argv)
84 {
85         if (argc == 2) {
86                 /* old 'btrfs filesystem balance <path>' syntax */
87                 struct btrfs_ioctl_balance_args args;
88
89                 memset(&args, 0, sizeof(args));
90                 args.flags |= BTRFS_BALANCE_TYPE_MASK;
91
92                 return do_balance(argv[1], &args);
93         }
94
95         return handle_command_group(&balance_cmd_group, argc, argv);
96 }