btrfs-progs: subvolume snapshot: use libbtrfsutil for snapshot
Call btrfs_util_subvolume_snapshot in cmd_subvolume_snapshot rather than calling the ioctl directly. Signed-off-by: Mark Harmstone <maharmstone@fb.com> Co-authored-by: Omar Sandoval <osandov@fb.com>
This commit is contained in:
parent
3ff4bf3dd8
commit
4419306730
|
@ -635,18 +635,11 @@ static int cmd_subvolume_snapshot(const struct cmd_struct *cmd, int argc, char *
|
||||||
{
|
{
|
||||||
char *subvol, *dst;
|
char *subvol, *dst;
|
||||||
int res, retval;
|
int res, retval;
|
||||||
int fd = -1, fddst = -1;
|
char *dstdir = NULL;
|
||||||
int len;
|
|
||||||
bool readonly = false;
|
|
||||||
char *dupname = NULL;
|
|
||||||
char *dupdir = NULL;
|
|
||||||
const char *newname;
|
|
||||||
char *dstdir;
|
|
||||||
enum btrfs_util_error err;
|
enum btrfs_util_error err;
|
||||||
struct btrfs_ioctl_vol_args_v2 args;
|
struct btrfs_util_qgroup_inherit *inherit = NULL;
|
||||||
struct btrfs_qgroup_inherit *inherit = NULL;
|
int flags = 0;
|
||||||
|
|
||||||
memset(&args, 0, sizeof(args));
|
|
||||||
optind = 0;
|
optind = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
int c = getopt(argc, argv, "i:r");
|
int c = getopt(argc, argv, "i:r");
|
||||||
|
@ -655,14 +648,14 @@ static int cmd_subvolume_snapshot(const struct cmd_struct *cmd, int argc, char *
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'i':
|
case 'i':
|
||||||
res = btrfs_qgroup_inherit_add_group(&inherit, optarg);
|
res = qgroup_inherit_add_group(&inherit, optarg);
|
||||||
if (res) {
|
if (res) {
|
||||||
retval = res;
|
retval = res;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
readonly = true;
|
flags |= BTRFS_UTIL_CREATE_SNAPSHOT_READ_ONLY;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usage_unknown_option(cmd, argv);
|
usage_unknown_option(cmd, argv);
|
||||||
|
@ -696,72 +689,49 @@ static int cmd_subvolume_snapshot(const struct cmd_struct *cmd, int argc, char *
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
|
char *dupname;
|
||||||
|
const char *newname;
|
||||||
|
|
||||||
dupname = strdup(subvol);
|
dupname = strdup(subvol);
|
||||||
newname = path_basename(dupname);
|
newname = path_basename(dupname);
|
||||||
dstdir = dst;
|
|
||||||
|
dstdir = malloc(strlen(dst) + 1 + strlen(newname) + 1);
|
||||||
|
if (!dstdir) {
|
||||||
|
error_msg(ERROR_MSG_MEMORY, NULL);
|
||||||
|
free(dupname);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dstdir[0] = 0;
|
||||||
|
strcpy(dstdir, dst);
|
||||||
|
strcat(dstdir, "/");
|
||||||
|
strcat(dstdir, newname);
|
||||||
|
|
||||||
|
free(dupname);
|
||||||
} else {
|
} else {
|
||||||
dupname = strdup(dst);
|
dstdir = strdup(dst);
|
||||||
newname = path_basename(dupname);
|
|
||||||
dupdir = strdup(dst);
|
|
||||||
dstdir = path_dirname(dupdir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!test_issubvolname(newname)) {
|
err = btrfs_util_subvolume_snapshot(subvol, dstdir, flags, NULL, inherit);
|
||||||
error("invalid snapshot name '%s'", newname);
|
if (err) {
|
||||||
goto out;
|
error_btrfs_util(err);
|
||||||
}
|
|
||||||
|
|
||||||
len = strlen(newname);
|
|
||||||
if (len > BTRFS_VOL_NAME_MAX) {
|
|
||||||
error("snapshot name too long '%s'", newname);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
fddst = btrfs_open_dir(dstdir);
|
|
||||||
if (fddst < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
fd = btrfs_open_dir(subvol);
|
|
||||||
if (fd < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (readonly)
|
|
||||||
args.flags |= BTRFS_SUBVOL_RDONLY;
|
|
||||||
|
|
||||||
args.fd = fd;
|
|
||||||
if (inherit) {
|
|
||||||
args.flags |= BTRFS_SUBVOL_QGROUP_INHERIT;
|
|
||||||
args.size = btrfs_qgroup_inherit_size(inherit);
|
|
||||||
args.qgroup_inherit = inherit;
|
|
||||||
}
|
|
||||||
strncpy_null(args.name, newname, sizeof(args.name));
|
|
||||||
|
|
||||||
res = ioctl(fddst, BTRFS_IOC_SNAP_CREATE_V2, &args);
|
|
||||||
if (res < 0) {
|
|
||||||
if (errno == ETXTBSY)
|
|
||||||
error("cannot snapshot '%s': source subvolume contains an active swapfile (%m)", subvol);
|
|
||||||
else
|
|
||||||
error("cannot snapshot '%s': %m", subvol);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = 0; /* success */
|
retval = 0; /* success */
|
||||||
|
|
||||||
if (readonly)
|
if (flags & BTRFS_UTIL_CREATE_SNAPSHOT_READ_ONLY)
|
||||||
pr_verbose(LOG_DEFAULT,
|
pr_verbose(LOG_DEFAULT,
|
||||||
"Create readonly snapshot of '%s' in '%s/%s'\n",
|
"Create readonly snapshot of '%s' in '%s'\n",
|
||||||
subvol, dstdir, newname);
|
subvol, dstdir);
|
||||||
else
|
else
|
||||||
pr_verbose(LOG_DEFAULT,
|
pr_verbose(LOG_DEFAULT,
|
||||||
"Create snapshot of '%s' in '%s/%s'\n",
|
"Create snapshot of '%s' in '%s'\n",
|
||||||
subvol, dstdir, newname);
|
subvol, dstdir);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
close(fddst);
|
free(dstdir);
|
||||||
close(fd);
|
btrfs_util_qgroup_inherit_destroy(inherit);
|
||||||
free(inherit);
|
|
||||||
free(dupname);
|
|
||||||
free(dupdir);
|
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue