]> git.sesse.net Git - bcachefs-tools-debian/blob - c_src/cmd_subvolume.c
99a302b8d2dd38b393009cfc7ae888a186817f07
[bcachefs-tools-debian] / c_src / cmd_subvolume.c
1 #include <errno.h>
2 #include <fcntl.h>
3 #include <getopt.h>
4 #include <libgen.h>
5 #include <stdbool.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <sys/ioctl.h>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14
15 #include "libbcachefs/bcachefs.h"
16 #include "libbcachefs/bcachefs_ioctl.h"
17 #include "cmds.h"
18 #include "libbcachefs.h"
19 #include "libbcachefs/opts.h"
20 #include "tools-util.h"
21
22 int subvolume_usage(void)
23 {
24         puts("bcachefs subvolume - manage subvolumes and snapshots\n"
25              "Usage: bcachefs subvolume <CMD> [OPTION]\n"
26              "\n"
27              "Commands:\n"
28              "  create                  create a subvolume\n"
29              "  delete                  delete a subvolume\n"
30              "  snapshot                create a snapshot\n"
31              "\n"
32              "Report bugs to <linux-bcachefs@vger.kernel.org>");
33         return 0;
34 }
35
36 static void subvolume_create_usage(void)
37 {
38         puts("bcachefs subvolume create - create a new subvolume\n"
39              "Usage: bcachefs subvolume create [OPTION]... path\n"
40              "\n"
41              "Options:\n"
42              "  -h, --help                  Display this help and exit\n"
43              "\n"
44              "Report bugs to <linux-bcachefs@vger.kernel.org>");
45 }
46
47 int cmd_subvolume_create(int argc, char *argv[])
48 {
49         static const struct option longopts[] = {
50                 { "help",               no_argument,            NULL, 'h' },
51                 { NULL }
52         };
53         char *path;
54         int opt;
55
56         while ((opt = getopt_long(argc, argv, "h", longopts, NULL)) != -1)
57                 switch (opt) {
58                 case 'h':
59                         subvolume_create_usage();
60                         exit(EXIT_SUCCESS);
61                 }
62         args_shift(optind);
63
64         while ((path = arg_pop())) {
65                 char *dir = dirname(strdup(path));
66
67                 struct bchfs_handle fs = bcache_fs_open(dir);
68
69                 struct bch_ioctl_subvolume i = {
70                         .dirfd          = AT_FDCWD,
71                         .mode           = 0777,
72                         .dst_ptr        = (unsigned long)path,
73                 };
74
75                 xioctl(fs.ioctl_fd, BCH_IOCTL_SUBVOLUME_CREATE, &i);
76                 bcache_fs_close(fs);
77         }
78
79         return 0;
80 }
81
82 static void subvolume_delete_usage(void)
83 {
84         puts("bcachefs subvolume delete - delete an existing subvolume\n"
85              "Usage: bcachefs subvolume delete [OPTION]... path\n"
86              "\n"
87              "Options:\n"
88              "  -h, --help                  Display this help and exit\n"
89              "\n"
90              "Report bugs to <linux-bcachefs@vger.kernel.org>");
91 }
92
93 int cmd_subvolume_delete(int argc, char *argv[])
94 {
95         static const struct option longopts[] = {
96                 { "help",               no_argument,            NULL, 'h' },
97                 { NULL }
98         };
99         char *path;
100         int opt;
101
102         while ((opt = getopt_long(argc, argv, "h", longopts, NULL)) != -1)
103                 switch (opt) {
104                 case 'h':
105                         subvolume_delete_usage();
106                         exit(EXIT_SUCCESS);
107                 }
108         args_shift(optind);
109
110         while ((path = arg_pop())) {
111                 char *dir = dirname(strdup(path));
112
113                 struct bchfs_handle fs = bcache_fs_open(dir);
114
115                 struct bch_ioctl_subvolume i = {
116                         .dirfd          = AT_FDCWD,
117                         .mode           = 0777,
118                         .dst_ptr        = (unsigned long)path,
119                 };
120
121                 xioctl(fs.ioctl_fd, BCH_IOCTL_SUBVOLUME_DESTROY, &i);
122                 bcache_fs_close(fs);
123         }
124
125         return 0;
126 }
127
128 static void snapshot_create_usage(void)
129 {
130         puts("bcachefs subvolume snapshot - create a snapshot \n"
131              "Usage: bcachefs subvolume snapshot [OPTION]... <source> <dest>\n"
132              "\n"
133              "Create a snapshot of <source> at <dest>. If specified, <source> must be a subvolume;\n"
134              "if not specified the snapshot will be of the subvolme containing <dest>.\n"
135              "Options:\n"
136              "  -r                          Make snapshot read only\n"
137              "  -h, --help                  Display this help and exit\n"
138              "\n"
139              "Report bugs to <linux-bcachefs@vger.kernel.org>");
140 }
141
142 int cmd_subvolume_snapshot(int argc, char *argv[])
143 {
144         static const struct option longopts[] = {
145                 { "help",               no_argument,            NULL, 'h' },
146                 { NULL }
147         };
148         unsigned flags = BCH_SUBVOL_SNAPSHOT_CREATE;
149         int opt;
150
151         while ((opt = getopt_long(argc, argv, "rh", longopts, NULL)) != -1)
152                 switch (opt) {
153                 case 'r':
154                         flags |= BCH_SUBVOL_SNAPSHOT_RO;
155                         break;
156                 case 'h':
157                         snapshot_create_usage();
158                         exit(EXIT_SUCCESS);
159                 }
160         args_shift(optind);
161
162         char *src = arg_pop();
163         char *dst = arg_pop();
164
165         if (argc)
166                 die("Too many arguments");
167
168         if (!dst)
169                 swap(src, dst);
170         if (!dst)
171                 die("Please specify a path to create");
172
173         char *dir = dirname(strdup(dst));
174
175         struct bchfs_handle fs = bcache_fs_open(dir);
176
177         struct bch_ioctl_subvolume i = {
178                 .flags          = flags,
179                 .dirfd          = AT_FDCWD,
180                 .mode           = 0777,
181                 .src_ptr        = (unsigned long)src,
182                 .dst_ptr        = (unsigned long)dst,
183         };
184
185         xioctl(fs.ioctl_fd, BCH_IOCTL_SUBVOLUME_CREATE, &i);
186         bcache_fs_close(fs);
187         return 0;
188 }