Skip to content

Commit 0e11b21

Browse files
osandovkdave
authored andcommitted
btrfs-progs: subvolume delete: add new option for recursive deletion
Add new option --recursive 'btrfs subvol delete', causing it to pass the BTRFS_UTIL_DELETE_SUBVOLUME_RECURSIVE flag through to libbtrfsutil. This can work in two modes, depending on the user: - regular user - this will skip subvolumes that are not accessible - root (CAP_SYS_ADMIN) - no limitations Pull-request: #861 Signed-off-by: Mark Harmstone <[email protected]> Co-authored-by: Omar Sandoval <[email protected]> Reviewed-by: Qu Wenruo <[email protected]> [ Add details to man page, fix indent in the doc. ] Signed-off-by: Qu Wenruo <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent a00c2b2 commit 0e11b21

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

Documentation/btrfs-subvolume.rst

+9
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,15 @@ delete [options] [<subvolume> [<subvolume>...]], delete -i|--subvolid <subvolid>
112112
-i|--subvolid <subvolid>
113113
subvolume id to be removed instead of the <path> that should point to the
114114
filesystem with the subvolume
115+
116+
-R|--recursive
117+
delete subvolumes beneath each subvolume recursively
118+
119+
This requires either `CAP_SYS_ADMIN` or the filesystem must be
120+
mounted with `user_subvol_rm_allowed` mount option.
121+
In the unprivileged case, subvolumes which cannot be accessed
122+
are skipped. The deletion is not atomic.
123+
115124
-v|--verbose
116125
(deprecated) alias for global *-v* option
117126

cmds/subvolume.c

+14-2
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,8 @@ static const char * const cmd_subvolume_delete_usage[] = {
347347
OPTLINE("-c|--commit-after", "wait for transaction commit at the end of the operation"),
348348
OPTLINE("-C|--commit-each", "wait for transaction commit after deleting each subvolume"),
349349
OPTLINE("-i|--subvolid", "subvolume id of the to be removed subvolume"),
350+
OPTLINE("-R|--recursive", "delete accessible subvolumes beneath each subvolume recursively, "
351+
"this is not atomic, may need root to delete subvolumes not accessible by the user"),
350352
OPTLINE("-v|--verbose", "deprecated, alias for global -v option"),
351353
HELPINFO_INSERT_GLOBALS,
352354
HELPINFO_INSERT_VERBOSE,
@@ -367,6 +369,7 @@ static int cmd_subvolume_delete(const struct cmd_struct *cmd, int argc, char **a
367369
char *path = NULL;
368370
int commit_mode = 0;
369371
bool subvol_path_not_found = false;
372+
int flags = 0;
370373
u8 fsid[BTRFS_FSID_SIZE];
371374
u64 subvolid = 0;
372375
char uuidbuf[BTRFS_UUID_UNPARSED_SIZE];
@@ -383,11 +386,12 @@ static int cmd_subvolume_delete(const struct cmd_struct *cmd, int argc, char **a
383386
{"commit-after", no_argument, NULL, 'c'},
384387
{"commit-each", no_argument, NULL, 'C'},
385388
{"subvolid", required_argument, NULL, 'i'},
389+
{"recursive", no_argument, NULL, 'R'},
386390
{"verbose", no_argument, NULL, 'v'},
387391
{NULL, 0, NULL, 0}
388392
};
389393

390-
c = getopt_long(argc, argv, "cCi:v", long_options, NULL);
394+
c = getopt_long(argc, argv, "cCi:Rv", long_options, NULL);
391395
if (c < 0)
392396
break;
393397

@@ -401,6 +405,9 @@ static int cmd_subvolume_delete(const struct cmd_struct *cmd, int argc, char **a
401405
case 'i':
402406
subvolid = arg_strtou64(optarg);
403407
break;
408+
case 'R':
409+
flags |= BTRFS_UTIL_DELETE_SUBVOLUME_RECURSIVE;
410+
break;
404411
case 'v':
405412
bconf_be_verbose();
406413
break;
@@ -416,6 +423,11 @@ static int cmd_subvolume_delete(const struct cmd_struct *cmd, int argc, char **a
416423
if (subvolid > 0 && check_argc_exact(argc - optind, 1))
417424
return 1;
418425

426+
if (subvolid > 0 && flags & BTRFS_UTIL_DELETE_SUBVOLUME_RECURSIVE) {
427+
error("option --recursive is not supported with --subvolid");
428+
return 1;
429+
}
430+
419431
pr_verbose(LOG_INFO, "Transaction commit: %s\n",
420432
!commit_mode ? "none (default)" :
421433
commit_mode == COMMIT_AFTER ? "at the end" : "after each");
@@ -528,7 +540,7 @@ static int cmd_subvolume_delete(const struct cmd_struct *cmd, int argc, char **a
528540

529541
/* Start deleting. */
530542
if (subvolid == 0)
531-
err = btrfs_util_delete_subvolume_fd(fd, vname, 0);
543+
err = btrfs_util_delete_subvolume_fd(fd, vname, flags);
532544
else
533545
err = btrfs_util_delete_subvolume_by_id_fd(fd, subvolid);
534546
if (err) {

0 commit comments

Comments
 (0)