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/units.h"
|
||||||
#include "common/format-output.h"
|
#include "common/format-output.h"
|
||||||
#include "common/tree-search.h"
|
#include "common/tree-search.h"
|
||||||
|
#include "common/parse-utils.h"
|
||||||
#include "cmds/commands.h"
|
#include "cmds/commands.h"
|
||||||
#include "cmds/qgroup.h"
|
#include "cmds/qgroup.h"
|
||||||
|
|
||||||
|
@ -140,28 +141,15 @@ static const char * const cmd_subvolume_create_usage[] = {
|
||||||
NULL
|
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)
|
bool create_parents)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
int len;
|
|
||||||
int fddst = -1;
|
|
||||||
char *dupname = NULL;
|
char *dupname = NULL;
|
||||||
char *dupdir = NULL;
|
char *dupdir = NULL;
|
||||||
const char *newname;
|
const char *newname;
|
||||||
char *dstdir;
|
char *dstdir;
|
||||||
|
enum btrfs_util_error err;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
dupname = strdup(dst);
|
dupname = strdup(dst);
|
||||||
if (!dupname) {
|
if (!dupname) {
|
||||||
|
@ -179,19 +167,6 @@ static int create_one_subvolume(const char *dst, struct btrfs_qgroup_inherit *in
|
||||||
}
|
}
|
||||||
dstdir = path_dirname(dupdir);
|
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) {
|
if (create_parents) {
|
||||||
char p[PATH_MAX] = { 0 };
|
char p[PATH_MAX] = { 0 };
|
||||||
char dstdir_dup[PATH_MAX];
|
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);
|
err = btrfs_util_subvolume_create(dst, 0, NULL, inherit);
|
||||||
if (fddst < 0) {
|
if (err) {
|
||||||
ret = fddst;
|
error_btrfs_util(err);
|
||||||
|
ret = -errno;
|
||||||
goto out;
|
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);
|
pr_verbose(LOG_DEFAULT, "Create subvolume '%s/%s'\n", dstdir, newname);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
close(fddst);
|
|
||||||
free(dupname);
|
free(dupname);
|
||||||
free(dupdir);
|
free(dupdir);
|
||||||
|
|
||||||
return ret;
|
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)
|
static int cmd_subvolume_create(const struct cmd_struct *cmd, int argc, char **argv)
|
||||||
{
|
{
|
||||||
int retval, ret;
|
int retval, ret;
|
||||||
struct btrfs_qgroup_inherit *inherit = NULL;
|
struct btrfs_util_qgroup_inherit *inherit = NULL;
|
||||||
bool has_error = false;
|
bool has_error = false;
|
||||||
bool create_parents = 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) {
|
switch (c) {
|
||||||
case 'i':
|
case 'i':
|
||||||
ret = btrfs_qgroup_inherit_add_group(&inherit, optarg);
|
ret = qgroup_inherit_add_group(&inherit, optarg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
retval = ret;
|
retval = ret;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -310,7 +295,7 @@ static int cmd_subvolume_create(const struct cmd_struct *cmd, int argc, char **a
|
||||||
if (!has_error)
|
if (!has_error)
|
||||||
retval = 0;
|
retval = 0;
|
||||||
out:
|
out:
|
||||||
free(inherit);
|
btrfs_util_qgroup_inherit_destroy(inherit);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue