]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/basic/btrfs-util.c
tree-wide: replace strjoin() with path_join()
[thirdparty/systemd.git] / src / basic / btrfs-util.c
index 48e819a7cbeac33c31dde8605798de2ec8767af0..10ca893da016fb9430327ee489519f6a101fea49 100644 (file)
@@ -3,8 +3,10 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <linux/btrfs_tree.h>
 #include <linux/fs.h>
 #include <linux/loop.h>
+#include <linux/magic.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/sysmacros.h>
 #include <unistd.h>
 
-#if HAVE_LINUX_BTRFS_H
-#include <linux/btrfs.h>
-#endif
-
 #include "alloc-util.h"
 #include "blockdev-util.h"
-#include "btrfs-ctree.h"
 #include "btrfs-util.h"
 #include "chattr-util.h"
 #include "copy.h"
@@ -31,7 +28,6 @@
 #include "fs-util.h"
 #include "io-util.h"
 #include "macro.h"
-#include "missing.h"
 #include "path-util.h"
 #include "rm-rf.h"
 #include "smack-util.h"
@@ -870,96 +866,6 @@ int btrfs_subvol_set_subtree_quota_limit(const char *path, uint64_t subvol_id, u
         return btrfs_subvol_set_subtree_quota_limit_fd(fd, subvol_id, referenced_max);
 }
 
-int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) {
-        struct btrfs_ioctl_vol_args args = {};
-        char p[SYS_BLOCK_PATH_MAX("/loop/backing_file")], q[DEV_NUM_PATH_MAX];
-        _cleanup_free_ char *backing = NULL;
-        _cleanup_close_ int loop_fd = -1, backing_fd = -1;
-        struct stat st;
-        dev_t dev = 0;
-        int r;
-
-        /* In contrast to btrfs quota ioctls ftruncate() cannot make sense of "infinity" or file sizes > 2^31 */
-        if (!FILE_SIZE_VALID(new_size))
-                return -EINVAL;
-
-        /* btrfs cannot handle file systems < 16M, hence use this as minimum */
-        if (new_size < 16*1024*1024)
-                new_size = 16*1024*1024;
-
-        r = btrfs_get_block_device_fd(fd, &dev);
-        if (r < 0)
-                return r;
-        if (r == 0)
-                return -ENODEV;
-
-        xsprintf_sys_block_path(p, "/loop/backing_file", dev);
-        r = read_one_line_file(p, &backing);
-        if (r == -ENOENT)
-                return -ENODEV;
-        if (r < 0)
-                return r;
-        if (isempty(backing) || !path_is_absolute(backing))
-                return -ENODEV;
-
-        backing_fd = open(backing, O_RDWR|O_CLOEXEC|O_NOCTTY);
-        if (backing_fd < 0)
-                return -errno;
-
-        if (fstat(backing_fd, &st) < 0)
-                return -errno;
-        if (!S_ISREG(st.st_mode))
-                return -ENODEV;
-
-        if (new_size == (uint64_t) st.st_size)
-                return 0;
-
-        if (grow_only && new_size < (uint64_t) st.st_size)
-                return -EINVAL;
-
-        xsprintf_dev_num_path(q, "block", dev);
-        loop_fd = open(q, O_RDWR|O_CLOEXEC|O_NOCTTY);
-        if (loop_fd < 0)
-                return -errno;
-
-        if (snprintf(args.name, sizeof(args.name), "%" PRIu64, new_size) >= (int) sizeof(args.name))
-                return -EINVAL;
-
-        if (new_size < (uint64_t) st.st_size) {
-                /* Decrease size: first decrease btrfs size, then shorten loopback */
-                if (ioctl(fd, BTRFS_IOC_RESIZE, &args) < 0)
-                        return -errno;
-        }
-
-        if (ftruncate(backing_fd, new_size) < 0)
-                return -errno;
-
-        if (ioctl(loop_fd, LOOP_SET_CAPACITY, 0) < 0)
-                return -errno;
-
-        if (new_size > (uint64_t) st.st_size) {
-                /* Increase size: first enlarge loopback, then increase btrfs size */
-                if (ioctl(fd, BTRFS_IOC_RESIZE, &args) < 0)
-                        return -errno;
-        }
-
-        /* Make sure the free disk space is correctly updated for both file systems */
-        (void) fsync(fd);
-        (void) fsync(backing_fd);
-
-        return 1;
-}
-
-int btrfs_resize_loopback(const char *p, uint64_t new_size, bool grow_only) {
-        _cleanup_close_ int fd = -1;
-
-        fd = open(p, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-        if (fd < 0)
-                return -errno;
-
-        return btrfs_resize_loopback_fd(fd, new_size, grow_only);
-}
-
 int btrfs_qgroupid_make(uint64_t level, uint64_t id, uint64_t *ret) {
         assert(ret);
 
@@ -1036,7 +942,7 @@ int btrfs_qgroup_destroy_recursive(int fd, uint64_t qgroupid) {
 
         /* Destroys the specified qgroup, but unassigns it from all
          * its parents first. Also, it recursively destroys all
-         * qgroups it is assgined to that have the same id part of the
+         * qgroups it is assigned to that have the same id part of the
          * qgroupid as the specified group. */
 
         r = btrfs_qgroupid_split(qgroupid, NULL, &subvol_id);
@@ -1503,7 +1409,12 @@ static int copy_subtree_quota_limits(int fd, uint64_t old_subvol, uint64_t new_s
         return changed;
 }
 
-static int subvol_snapshot_children(int old_fd, int new_fd, const char *subvolume, uint64_t old_subvol_id, BtrfsSnapshotFlags flags) {
+static int subvol_snapshot_children(
+                int old_fd,
+                int new_fd,
+                const char *subvolume,
+                uint64_t old_subvol_id,
+                BtrfsSnapshotFlags flags) {
 
         struct btrfs_ioctl_search_args args = {
                 .key.tree_id = BTRFS_ROOT_TREE_OBJECTID,
@@ -1619,7 +1530,7 @@ static int subvol_snapshot_children(int old_fd, int new_fd, const char *subvolum
                         if (old_child_fd < 0)
                                 return -errno;
 
-                        np = strjoin(subvolume, "/", ino_args.name);
+                        np = path_join(subvolume, ino_args.name);
                         if (!np)
                                 return -ENOMEM;
 
@@ -1683,7 +1594,14 @@ static int subvol_snapshot_children(int old_fd, int new_fd, const char *subvolum
         return 0;
 }
 
-int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlags flags) {
+int btrfs_subvol_snapshot_fd_full(
+                int old_fd,
+                const char *new_path,
+                BtrfsSnapshotFlags flags,
+                copy_progress_path_t progress_path,
+                copy_progress_bytes_t progress_bytes,
+                void *userdata) {
+
         _cleanup_close_ int new_fd = -1;
         const char *subvolume;
         int r;
@@ -1711,7 +1629,7 @@ int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlag
                 } else if (r < 0)
                         return r;
 
-                r = copy_directory_fd(old_fd, new_path, COPY_MERGE|COPY_REFLINK);
+                r = copy_directory_fd_full(old_fd, new_path, COPY_MERGE|COPY_REFLINK|COPY_SAME_MOUNT, progress_path, progress_bytes, userdata);
                 if (r < 0)
                         goto fallback_fail;
 
@@ -1748,7 +1666,14 @@ int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlag
         return subvol_snapshot_children(old_fd, new_fd, subvolume, 0, flags);
 }
 
-int btrfs_subvol_snapshot(const char *old_path, const char *new_path, BtrfsSnapshotFlags flags) {
+int btrfs_subvol_snapshot_full(
+                const char *old_path,
+                const char *new_path,
+                BtrfsSnapshotFlags flags,
+                copy_progress_path_t progress_path,
+                copy_progress_bytes_t progress_bytes,
+                void *userdata) {
+
         _cleanup_close_ int old_fd = -1;
 
         assert(old_path);
@@ -1758,7 +1683,7 @@ int btrfs_subvol_snapshot(const char *old_path, const char *new_path, BtrfsSnaps
         if (old_fd < 0)
                 return -errno;
 
-        return btrfs_subvol_snapshot_fd(old_fd, new_path, flags);
+        return btrfs_subvol_snapshot_fd_full(old_fd, new_path, flags, progress_path, progress_bytes, userdata);
 }
 
 int btrfs_qgroup_find_parents(int fd, uint64_t qgroupid, uint64_t **ret) {