X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Fbtrfs-util.c;h=b34ac8b15a80260c13cef09701bf1673d79d84df;hb=374c22b351e43ce4ef70ef0ad1bd1e4e520f9a28;hp=bd100eef0b435b710f7817883cbc0c2f841b2934;hpb=5743a5852d2ab6ad7f589c255afcfdf523d60ba8;p=elogind.git diff --git a/src/shared/btrfs-util.c b/src/shared/btrfs-util.c index bd100eef0..b34ac8b15 100644 --- a/src/shared/btrfs-util.c +++ b/src/shared/btrfs-util.c @@ -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;