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;
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;
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;