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 <maharmstone@fb.com> Co-authored-by: Omar Sandoval <osandov@fb.com>
This commit is contained in:
parent
ec8a6b1536
commit
3ff4bf3dd8
|
@ -46,6 +46,7 @@
|
|||
#include "common/units.h"
|
||||
#include "common/format-output.h"
|
||||
#include "common/tree-search.h"
|
||||
#include "common/parse-utils.h"
|
||||
#include "cmds/commands.h"
|
||||
#include "cmds/qgroup.h"
|
||||
|
||||
|
@ -140,28 +141,15 @@ static const char * const cmd_subvolume_create_usage[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *inherit,
|
||||
static int create_one_subvolume(const char *dst, struct btrfs_util_qgroup_inherit *inherit,
|
||||
bool create_parents)
|
||||
{
|
||||
int ret;
|
||||
int len;
|
||||
int fddst = -1;
|
||||
char *dupname = NULL;
|
||||
char *dupdir = NULL;
|
||||
const char *newname;
|
||||
char *dstdir;
|
||||
|
||||
ret = path_is_dir(dst);
|
||||
if (ret < 0 && ret != -ENOENT) {
|
||||
errno = -ret;
|
||||
error("cannot access %s: %m", dst);
|
||||
goto out;
|
||||
}
|
||||
if (ret >= 0) {
|
||||
error("target path already exists: %s", dst);
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
enum btrfs_util_error err;
|
||||
|
||||
dupname = strdup(dst);
|
||||
if (!dupname) {
|
||||
|
@ -179,19 +167,6 @@ static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *in
|
|||
}
|
||||
dstdir = path_dirname(dupdir);
|
||||
|
||||
if (!test_issubvolname(newname)) {
|
||||
error("invalid subvolume name: %s", newname);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
len = strlen(newname);
|
||||
if (len > BTRFS_VOL_NAME_MAX) {
|
||||
error("subvolume name too long: %s", newname);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (create_parents) {
|
||||
char p[PATH_MAX] = { 0 };
|
||||
char dstdir_dup[PATH_MAX];
|
||||
|
@ -223,47 +198,57 @@ static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *in
|
|||
}
|
||||
}
|
||||
|
||||
fddst = btrfs_open_dir(dstdir);
|
||||
if (fddst < 0) {
|
||||
ret = fddst;
|
||||
err = btrfs_util_subvolume_create(dst, 0, NULL, inherit);
|
||||
if (err) {
|
||||
error_btrfs_util(err);
|
||||
ret = -errno;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (inherit) {
|
||||
struct btrfs_ioctl_vol_args_v2 args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
strncpy_null(args.name, newname, sizeof(args.name));
|
||||
args.flags |= BTRFS_SUBVOL_QGROUP_INHERIT;
|
||||
args.size = btrfs_qgroup_inherit_size(inherit);
|
||||
args.qgroup_inherit = inherit;
|
||||
|
||||
ret = ioctl(fddst, BTRFS_IOC_SUBVOL_CREATE_V2, &args);
|
||||
} else {
|
||||
struct btrfs_ioctl_vol_args args;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
strncpy_null(args.name, newname, sizeof(args.name));
|
||||
ret = ioctl(fddst, BTRFS_IOC_SUBVOL_CREATE, &args);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
error("cannot create subvolume: %m");
|
||||
goto out;
|
||||
}
|
||||
pr_verbose(LOG_DEFAULT, "Create subvolume '%s/%s'\n", dstdir, newname);
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
close(fddst);
|
||||
free(dupname);
|
||||
free(dupdir);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qgroup_inherit_add_group(struct btrfs_util_qgroup_inherit **inherit,
|
||||
const char *arg)
|
||||
{
|
||||
enum btrfs_util_error err;
|
||||
u64 qgroupid;
|
||||
|
||||
if (!*inherit) {
|
||||
err = btrfs_util_qgroup_inherit_create(0, inherit);
|
||||
if (err) {
|
||||
error_btrfs_util(err);
|
||||
return -errno;
|
||||
}
|
||||
}
|
||||
|
||||
qgroupid = parse_qgroupid_or_path(optarg);
|
||||
if (qgroupid == 0) {
|
||||
error("invalid qgroup specification, qgroupid must not be 0");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = btrfs_util_qgroup_inherit_add_group(inherit, qgroupid);
|
||||
if (err) {
|
||||
error_btrfs_util(err);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cmd_subvolume_create(const struct cmd_struct *cmd, int argc, char **argv)
|
||||
{
|
||||
int retval, ret;
|
||||
struct btrfs_qgroup_inherit *inherit = NULL;
|
||||
struct btrfs_util_qgroup_inherit *inherit = NULL;
|
||||
bool has_error = false;
|
||||
bool create_parents = false;
|
||||
|
||||
|
@ -281,7 +266,7 @@ static int cmd_subvolume_create(const struct cmd_struct *cmd, int argc, char **a
|
|||
|
||||
switch (c) {
|
||||
case 'i':
|
||||
ret = btrfs_qgroup_inherit_add_group(&inherit, optarg);
|
||||
ret = qgroup_inherit_add_group(&inherit, optarg);
|
||||
if (ret) {
|
||||
retval = ret;
|
||||
goto out;
|
||||
|
@ -310,7 +295,7 @@ static int cmd_subvolume_create(const struct cmd_struct *cmd, int argc, char **a
|
|||
if (!has_error)
|
||||
retval = 0;
|
||||
out:
|
||||
free(inherit);
|
||||
btrfs_util_qgroup_inherit_destroy(inherit);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue