chiark / gitweb /
missing: add __NR_getrandom for powerpc architecture
[elogind.git] / src / shared / btrfs-util.c
index bd100eef0b435b710f7817883cbc0c2f841b2934..b34ac8b15a80260c13cef09701bf1673d79d84df 100644 (file)
@@ -228,14 +228,18 @@ int btrfs_subvol_remove(const char *path) {
         return 0;
 }
 
-int btrfs_subvol_set_read_only(const char *path, bool b) {
-        _cleanup_close_ int fd = -1;
+int btrfs_subvol_set_read_only_fd(int fd, bool b) {
         uint64_t flags, nflags;
+        struct stat st;
 
-        fd = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
-        if (fd < 0)
+        assert(fd >= 0);
+
+        if (fstat(fd, &st) < 0)
                 return -errno;
 
+        if (!S_ISDIR(st.st_mode) || st.st_ino != 256)
+                return -EINVAL;
+
         if (ioctl(fd, BTRFS_IOC_SUBVOL_GETFLAGS, &flags) < 0)
                 return -errno;
 
@@ -253,6 +257,16 @@ int btrfs_subvol_set_read_only(const char *path, bool b) {
         return 0;
 }
 
+int btrfs_subvol_set_read_only(const char *path, bool b) {
+        _cleanup_close_ int fd = -1;
+
+        fd = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
+        if (fd < 0)
+                return -errno;
+
+        return btrfs_subvol_set_read_only_fd(fd, b);
+}
+
 int btrfs_subvol_get_read_only_fd(int fd) {
         uint64_t flags;
 
@@ -275,6 +289,26 @@ int btrfs_reflink(int infd, int outfd) {
         return 0;
 }
 
+int btrfs_clone_range(int infd, uint64_t in_offset, int outfd, uint64_t out_offset, uint64_t sz) {
+        struct btrfs_ioctl_clone_range_args args = {
+                .src_fd = infd,
+                .src_offset = in_offset,
+                .src_length = sz,
+                .dest_offset = out_offset,
+        };
+        int r;
+
+        assert(infd >= 0);
+        assert(outfd >= 0);
+        assert(sz > 0);
+
+        r = ioctl(outfd, BTRFS_IOC_CLONE_RANGE, &args);
+        if (r < 0)
+                return -errno;
+
+        return 0;
+}
+
 int btrfs_get_block_device(const char *path, dev_t *dev) {
         struct btrfs_ioctl_fs_info_args fsi = {};
         _cleanup_close_ int fd = -1;