diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/btrfs-util.c | 53 | ||||
-rw-r--r-- | src/shared/btrfs-util.h | 2 |
2 files changed, 32 insertions, 23 deletions
diff --git a/src/shared/btrfs-util.c b/src/shared/btrfs-util.c index 256c5a6995..23a22db662 100644 --- a/src/shared/btrfs-util.c +++ b/src/shared/btrfs-util.c @@ -101,48 +101,42 @@ int btrfs_is_snapshot(int fd) { return F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC); } -int btrfs_subvol_snapshot(const char *old_path, const char *new_path, bool read_only, bool fallback_copy) { +int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, bool read_only, bool fallback_copy) { struct btrfs_ioctl_vol_args_v2 args = { .flags = read_only ? BTRFS_SUBVOL_RDONLY : 0, }; - _cleanup_close_ int old_fd = -1, new_fd = -1; + _cleanup_close_ int new_fd = -1; const char *subvolume; int r; - assert(old_path); - - old_fd = open(old_path, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY); - if (old_fd < 0) - return -errno; + assert(new_path); r = btrfs_is_snapshot(old_fd); if (r < 0) return r; if (r == 0) { + if (!fallback_copy) + return -EISDIR; - if (fallback_copy) { - r = btrfs_subvol_make(new_path); - if (r < 0) - return r; + r = btrfs_subvol_make(new_path); + if (r < 0) + return r; + + r = copy_directory_fd(old_fd, new_path, true); + if (r < 0) { + btrfs_subvol_remove(new_path); + return r; + } - r = copy_directory_fd(old_fd, new_path, true); + if (read_only) { + r = btrfs_subvol_set_read_only(new_path, true); if (r < 0) { btrfs_subvol_remove(new_path); return r; } - - if (read_only) { - r = btrfs_subvol_set_read_only(new_path, true); - if (r < 0) { - btrfs_subvol_remove(new_path); - return r; - } - } - - return 0; } - return -EISDIR; + return 0; } r = extract_subvolume_name(new_path, &subvolume); @@ -162,6 +156,19 @@ int btrfs_subvol_snapshot(const char *old_path, const char *new_path, bool read_ return 0; } +int btrfs_subvol_snapshot(const char *old_path, const char *new_path, bool read_only, bool fallback_copy) { + _cleanup_close_ int old_fd = -1; + + assert(old_path); + assert(new_path); + + old_fd = open(old_path, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY); + if (old_fd < 0) + return -errno; + + return btrfs_subvol_snapshot_fd(old_fd, new_path, read_only, fallback_copy); +} + int btrfs_subvol_make(const char *path) { struct btrfs_ioctl_vol_args args = {}; _cleanup_close_ int fd = -1; diff --git a/src/shared/btrfs-util.h b/src/shared/btrfs-util.h index a2c246b8d6..cb85b71d74 100644 --- a/src/shared/btrfs-util.h +++ b/src/shared/btrfs-util.h @@ -48,6 +48,8 @@ int btrfs_is_snapshot(int fd); int btrfs_subvol_make(const char *path); int btrfs_subvol_make_label(const char *path); int btrfs_subvol_remove(const char *path); + +int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, bool read_only, bool fallback_copy); int btrfs_subvol_snapshot(const char *old_path, const char *new_path, bool read_only, bool fallback_copy); int btrfs_subvol_set_read_only_fd(int fd, bool b); |