Btrfs-progs: btrfs subvolume delete could delete subvolumes

With this user will be able to provide more than one subvolume
to delete.
eg: btrfs subvolume delete <subvol1> <subvol2>

Signed-off-by: Anand Jain <anand.jain@oracle.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
master
Anand Jain 2012-09-21 00:54:08 -06:00 committed by root
parent 8ce1873c2a
commit 6500965277
2 changed files with 26 additions and 14 deletions

View File

@ -187,31 +187,34 @@ int test_issubvolume(char *path)
} }
static const char * const cmd_subvol_delete_usage[] = { static const char * const cmd_subvol_delete_usage[] = {
"btrfs subvolume delete <name>", "btrfs subvolume delete <subvolume> [<subvolume>...]",
"Delete a subvolume", "Delete subvolume(s)",
NULL NULL
}; };
static int cmd_subvol_delete(int argc, char **argv) static int cmd_subvol_delete(int argc, char **argv)
{ {
int res, fd, len, e; int res, fd, len, e, cnt = 1, ret = 0;
struct btrfs_ioctl_vol_args args; struct btrfs_ioctl_vol_args args;
char *dname, *vname, *cpath; char *dname, *vname, *cpath;
char *path; char *path;
if (check_argc_exact(argc, 2)) if (argc < 2)
usage(cmd_subvol_delete_usage); usage(cmd_subvol_delete_usage);
path = argv[1]; again:
path = argv[cnt];
res = test_issubvolume(path); res = test_issubvolume(path);
if(res<0){ if(res<0){
fprintf(stderr, "ERROR: error accessing '%s'\n", path); fprintf(stderr, "ERROR: error accessing '%s'\n", path);
return 12; ret = 12;
goto out;
} }
if(!res){ if(!res){
fprintf(stderr, "ERROR: '%s' is not a subvolume\n", path); fprintf(stderr, "ERROR: '%s' is not a subvolume\n", path);
return 13; ret = 13;
goto out;
} }
cpath = realpath(path, 0); cpath = realpath(path, 0);
@ -225,21 +228,24 @@ static int cmd_subvol_delete(int argc, char **argv)
strchr(vname, '/') ){ strchr(vname, '/') ){
fprintf(stderr, "ERROR: incorrect subvolume name ('%s')\n", fprintf(stderr, "ERROR: incorrect subvolume name ('%s')\n",
vname); vname);
return 14; ret = 14;
goto out;
} }
len = strlen(vname); len = strlen(vname);
if (len == 0 || len >= BTRFS_VOL_NAME_MAX) { if (len == 0 || len >= BTRFS_VOL_NAME_MAX) {
fprintf(stderr, "ERROR: snapshot name too long ('%s)\n", fprintf(stderr, "ERROR: snapshot name too long ('%s)\n",
vname); vname);
return 14; ret = 14;
goto out;
} }
fd = open_file_or_dir(dname); fd = open_file_or_dir(dname);
if (fd < 0) { if (fd < 0) {
close(fd); close(fd);
fprintf(stderr, "ERROR: can't access to '%s'\n", dname); fprintf(stderr, "ERROR: can't access to '%s'\n", dname);
return 12; ret = 12;
goto out;
} }
printf("Delete subvolume '%s/%s'\n", dname, vname); printf("Delete subvolume '%s/%s'\n", dname, vname);
@ -253,10 +259,16 @@ static int cmd_subvol_delete(int argc, char **argv)
if(res < 0 ){ if(res < 0 ){
fprintf( stderr, "ERROR: cannot delete '%s/%s' - %s\n", fprintf( stderr, "ERROR: cannot delete '%s/%s' - %s\n",
dname, vname, strerror(e)); dname, vname, strerror(e));
return 11; ret = 11;
goto out;
} }
return 0; out:
cnt++;
if (cnt < argc)
goto again;
return ret;
} }
static const char * const cmd_subvol_list_usage[] = { static const char * const cmd_subvol_list_usage[] = {

View File

@ -7,7 +7,7 @@ btrfs \- control a btrfs filesystem
.SH SYNOPSIS .SH SYNOPSIS
\fBbtrfs\fP \fBsubvolume snapshot\fP\fI [-r] <source> [<dest>/]<name>\fP \fBbtrfs\fP \fBsubvolume snapshot\fP\fI [-r] <source> [<dest>/]<name>\fP
.PP .PP
\fBbtrfs\fP \fBsubvolume delete\fP\fI <subvolume>\fP \fBbtrfs\fP \fBsubvolume delete\fP\fI <subvolume> [<subvolume>...]\fP
.PP .PP
\fBbtrfs\fP \fBsubvolume create\fP\fI [<dest>/]<name>\fP \fBbtrfs\fP \fBsubvolume create\fP\fI [<dest>/]<name>\fP
.PP .PP
@ -98,7 +98,7 @@ subvolume, \fBbtrfs\fR returns an error. If \fI-r\fR is given, the snapshot
will be readonly. will be readonly.
.TP .TP
\fBsubvolume delete\fR\fI <subvolume>\fR \fBsubvolume delete\fR\fI <subvolume> [<subvolume>...]\fR
Delete the subvolume \fI<subvolume>\fR. If \fI<subvolume>\fR is not a Delete the subvolume \fI<subvolume>\fR. If \fI<subvolume>\fR is not a
subvolume, \fBbtrfs\fR returns an error. subvolume, \fBbtrfs\fR returns an error.
.TP .TP