From 3a0c78409d8c69699e942838f48efb5f3556f82b Mon Sep 17 00:00:00 2001 From: Mark Harmstone Date: Wed, 4 Sep 2024 11:18:29 +0100 Subject: [PATCH] btrfs-progs: add option for recursive subvol snapshots Adds an option -R to btrfs subvolume snapshot, corresponding to the flag BTRFS_UTIL_CREATE_SNAPSHOT_RECURSIVE. This is another resubmission of a missed patch of Omar's from 2018: https://lore.kernel.org/all/e42cdc5d5287269faf4d09e8c9786d0b3adeb658.1516991902.git.osandov@fb.com/ Signed-off-by: Mark Harmstone Co-authored-by: Omar Sandoval --- Documentation/btrfs-subvolume.rst | 8 +++++++- cmds/subvolume.c | 15 +++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Documentation/btrfs-subvolume.rst b/Documentation/btrfs-subvolume.rst index eed602f9b..6c2eda2d7 100644 --- a/Documentation/btrfs-subvolume.rst +++ b/Documentation/btrfs-subvolume.rst @@ -252,17 +252,23 @@ show [options] -u|--uuid UUID show details about subvolume with the given *UUID*, looked up in *path* -snapshot [-r] [-i ] |[/] +snapshot [-r|-R] [-i ] |[/] Create a snapshot of the subvolume *source* with the name *name* in the *dest* directory. If only *dest* is given, the subvolume will be named the basename of *source*. If *source* is not a subvolume, btrfs returns an error. + If you wish to recursively create a readonly snapshot, you can run + :command:`btrfs property set ro true` on each subvolume after this command completes. + ``Options`` -r Make the new snapshot read only. + -R|--recursive + Recursively snapshot subvolumes beneath the source. This option cannot be + combined with -r. -i Add the newly created subvolume to a qgroup. This option can be given multiple times. diff --git a/cmds/subvolume.c b/cmds/subvolume.c index f34d94009..d29118cc4 100644 --- a/cmds/subvolume.c +++ b/cmds/subvolume.c @@ -616,7 +616,7 @@ static int cmd_subvolume_delete(const struct cmd_struct *cmd, int argc, char **a static DEFINE_COMMAND_WITH_FLAGS(subvolume_delete, "delete", CMD_DRY_RUN); static const char * const cmd_subvolume_snapshot_usage[] = { - "btrfs subvolume snapshot [-r] [-i ] { / | }", + "btrfs subvolume snapshot [-r|-R] [-i ] { / | }", "", "Create a snapshot of a . Call it and place it in the .", "( will look like a new sub-directory, but is actually a btrfs subvolume", @@ -625,6 +625,7 @@ static const char * const cmd_subvolume_snapshot_usage[] = { "When only is given, the subvolume will be named the basename of .", "", OPTLINE("-r", "make the new snapshot readonly"), + OPTLINE("-R|--recursive", "recursively snapshot subvolumes beneath the source; this option cannot be combined with -r"), OPTLINE("-i ", "Add the new snapshot to a qgroup (a quota group). This option can be given multiple times."), HELPINFO_INSERT_GLOBALS, HELPINFO_INSERT_QUIET, @@ -642,7 +643,7 @@ static int cmd_subvolume_snapshot(const struct cmd_struct *cmd, int argc, char * optind = 0; while (1) { - int c = getopt(argc, argv, "i:r"); + int c = getopt(argc, argv, "i:rR"); if (c < 0) break; @@ -657,11 +658,21 @@ static int cmd_subvolume_snapshot(const struct cmd_struct *cmd, int argc, char * case 'r': flags |= BTRFS_UTIL_CREATE_SNAPSHOT_READ_ONLY; break; + case 'R': + flags |= BTRFS_UTIL_CREATE_SNAPSHOT_RECURSIVE; + break; default: usage_unknown_option(cmd, argv); } } + if ((flags & BTRFS_UTIL_CREATE_SNAPSHOT_READ_ONLY) && + (flags & BTRFS_UTIL_CREATE_SNAPSHOT_RECURSIVE)) { + error("-r and -R cannot be combined"); + retval = 1; + goto out; + } + if (check_argc_exact(argc - optind, 2)) { retval = 1; goto out;