Skip to content

Commit 3ff4bf3

Browse files
maharmstoneosandov
authored andcommitted
btrfs-progs: subvolume create: use libbtrfsutil for creation
Call btrfs_util_subvolume_create in create_one_subvolume rather than calling the ioctl directly. Pull-request: #878 Signed-off-by: Mark Harmstone <[email protected]> Co-authored-by: Omar Sandoval <[email protected]>
1 parent ec8a6b1 commit 3ff4bf3

File tree

1 file changed

+41
-56
lines changed

1 file changed

+41
-56
lines changed

cmds/subvolume.c

Lines changed: 41 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "common/units.h"
4747
#include "common/format-output.h"
4848
#include "common/tree-search.h"
49+
#include "common/parse-utils.h"
4950
#include "cmds/commands.h"
5051
#include "cmds/qgroup.h"
5152

@@ -140,28 +141,15 @@ static const char * const cmd_subvolume_create_usage[] = {
140141
NULL
141142
};
142143

143-
static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *inherit,
144+
static int create_one_subvolume(const char *dst, struct btrfs_util_qgroup_inherit *inherit,
144145
bool create_parents)
145146
{
146147
int ret;
147-
int len;
148-
int fddst = -1;
149148
char *dupname = NULL;
150149
char *dupdir = NULL;
151150
const char *newname;
152151
char *dstdir;
153-
154-
ret = path_is_dir(dst);
155-
if (ret < 0 && ret != -ENOENT) {
156-
errno = -ret;
157-
error("cannot access %s: %m", dst);
158-
goto out;
159-
}
160-
if (ret >= 0) {
161-
error("target path already exists: %s", dst);
162-
ret = -EEXIST;
163-
goto out;
164-
}
152+
enum btrfs_util_error err;
165153

166154
dupname = strdup(dst);
167155
if (!dupname) {
@@ -179,19 +167,6 @@ static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *in
179167
}
180168
dstdir = path_dirname(dupdir);
181169

182-
if (!test_issubvolname(newname)) {
183-
error("invalid subvolume name: %s", newname);
184-
ret = -EINVAL;
185-
goto out;
186-
}
187-
188-
len = strlen(newname);
189-
if (len > BTRFS_VOL_NAME_MAX) {
190-
error("subvolume name too long: %s", newname);
191-
ret = -EINVAL;
192-
goto out;
193-
}
194-
195170
if (create_parents) {
196171
char p[PATH_MAX] = { 0 };
197172
char dstdir_dup[PATH_MAX];
@@ -223,47 +198,57 @@ static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *in
223198
}
224199
}
225200

226-
fddst = btrfs_open_dir(dstdir);
227-
if (fddst < 0) {
228-
ret = fddst;
201+
err = btrfs_util_subvolume_create(dst, 0, NULL, inherit);
202+
if (err) {
203+
error_btrfs_util(err);
204+
ret = -errno;
229205
goto out;
230206
}
231207

232-
if (inherit) {
233-
struct btrfs_ioctl_vol_args_v2 args;
208+
pr_verbose(LOG_DEFAULT, "Create subvolume '%s/%s'\n", dstdir, newname);
234209

235-
memset(&args, 0, sizeof(args));
236-
strncpy_null(args.name, newname, sizeof(args.name));
237-
args.flags |= BTRFS_SUBVOL_QGROUP_INHERIT;
238-
args.size = btrfs_qgroup_inherit_size(inherit);
239-
args.qgroup_inherit = inherit;
210+
ret = 0;
240211

241-
ret = ioctl(fddst, BTRFS_IOC_SUBVOL_CREATE_V2, &args);
242-
} else {
243-
struct btrfs_ioctl_vol_args args;
212+
out:
213+
free(dupname);
214+
free(dupdir);
244215

245-
memset(&args, 0, sizeof(args));
246-
strncpy_null(args.name, newname, sizeof(args.name));
247-
ret = ioctl(fddst, BTRFS_IOC_SUBVOL_CREATE, &args);
216+
return ret;
217+
}
218+
219+
static int qgroup_inherit_add_group(struct btrfs_util_qgroup_inherit **inherit,
220+
const char *arg)
221+
{
222+
enum btrfs_util_error err;
223+
u64 qgroupid;
224+
225+
if (!*inherit) {
226+
err = btrfs_util_qgroup_inherit_create(0, inherit);
227+
if (err) {
228+
error_btrfs_util(err);
229+
return -errno;
230+
}
248231
}
249232

250-
if (ret < 0) {
251-
error("cannot create subvolume: %m");
252-
goto out;
233+
qgroupid = parse_qgroupid_or_path(optarg);
234+
if (qgroupid == 0) {
235+
error("invalid qgroup specification, qgroupid must not be 0");
236+
return -EINVAL;
253237
}
254-
pr_verbose(LOG_DEFAULT, "Create subvolume '%s/%s'\n", dstdir, newname);
255238

256-
out:
257-
close(fddst);
258-
free(dupname);
259-
free(dupdir);
239+
err = btrfs_util_qgroup_inherit_add_group(inherit, qgroupid);
240+
if (err) {
241+
error_btrfs_util(err);
242+
return -errno;
243+
}
260244

261-
return ret;
245+
return 0;
262246
}
247+
263248
static int cmd_subvolume_create(const struct cmd_struct *cmd, int argc, char **argv)
264249
{
265250
int retval, ret;
266-
struct btrfs_qgroup_inherit *inherit = NULL;
251+
struct btrfs_util_qgroup_inherit *inherit = NULL;
267252
bool has_error = false;
268253
bool create_parents = false;
269254

@@ -281,7 +266,7 @@ static int cmd_subvolume_create(const struct cmd_struct *cmd, int argc, char **a
281266

282267
switch (c) {
283268
case 'i':
284-
ret = btrfs_qgroup_inherit_add_group(&inherit, optarg);
269+
ret = qgroup_inherit_add_group(&inherit, optarg);
285270
if (ret) {
286271
retval = ret;
287272
goto out;
@@ -310,7 +295,7 @@ static int cmd_subvolume_create(const struct cmd_struct *cmd, int argc, char **a
310295
if (!has_error)
311296
retval = 0;
312297
out:
313-
free(inherit);
298+
btrfs_util_qgroup_inherit_destroy(inherit);
314299

315300
return retval;
316301
}

0 commit comments

Comments
 (0)