return RET_NERRNO(ioctl(outfd, BTRFS_IOC_CLONE_RANGE, &args));
}
-int btrfs_get_block_device_fd(int fd, dev_t *dev) {
+int btrfs_get_block_device_at(int dir_fd, const char *path, dev_t *ret) {
struct btrfs_ioctl_fs_info_args fsi = {};
- _cleanup_close_ int regfd = -EBADF;
+ _cleanup_close_ int fd = -EBADF;
uint64_t id;
int r;
- assert(fd >= 0);
- assert(dev);
+ assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
+ assert(path);
+ assert(ret);
- fd = fd_reopen_condition(fd, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY, O_PATH, ®fd);
+ fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY, 0);
if (fd < 0)
return fd;
/* We won't do this for btrfs RAID */
if (fsi.num_devices != 1) {
- *dev = 0;
+ *ret = 0;
return 0;
}
if (major(st.st_rdev) == 0)
return -ENODEV;
- *dev = st.st_rdev;
+ *ret = st.st_rdev;
return 1;
}
return -ENODEV;
}
-int btrfs_get_block_device(const char *path, dev_t *dev) {
- _cleanup_close_ int fd = -EBADF;
-
- assert(path);
- assert(dev);
-
- fd = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
- if (fd < 0)
- return -errno;
-
- return btrfs_get_block_device_fd(fd, dev);
-}
-
int btrfs_subvol_get_id_fd(int fd, uint64_t *ret) {
struct btrfs_ioctl_ino_lookup_args args = {
.objectid = BTRFS_FIRST_FREE_OBJECTID
int btrfs_reflink(int infd, int outfd);
int btrfs_clone_range(int infd, uint64_t in_offset, int ofd, uint64_t out_offset, uint64_t sz);
-int btrfs_get_block_device_fd(int fd, dev_t *dev);
-int btrfs_get_block_device(const char *path, dev_t *dev);
+int btrfs_get_block_device_at(int dir_fd, const char *path, dev_t *ret);
+static inline int btrfs_get_block_device(const char *path, dev_t *ret) {
+ return btrfs_get_block_device_at(AT_FDCWD, path, ret);
+}
+static inline int btrfs_get_block_device_fd(int fd, dev_t *ret) {
+ return btrfs_get_block_device_at(fd, "", ret);
+}
int btrfs_defrag_fd(int fd);
int btrfs_defrag(const char *p);
if (!ret_dev)
return 0;
- if (sxa.sx.stx_dev_major == 0) { /* Hmm, maybe a btrfs device, and the caller asked for the backing device? Then let's try to get it. */
- _cleanup_close_ int real_fd = -EBADF;
-
- /* The statx() above we can execute on an O_PATH fd. But the btrfs ioctl we cannot. Hence
- * acquire a "real" fd first, without the O_PATH flag. */
-
- real_fd = fd_reopen(fd, O_DIRECTORY|O_CLOEXEC);
- if (real_fd < 0)
- return real_fd;
-
- return btrfs_get_block_device_fd(real_fd, ret_dev);
- }
+ if (sxa.sx.stx_dev_major == 0) /* Hmm, maybe a btrfs device, and the caller asked for the backing device? Then let's try to get it. */
+ return btrfs_get_block_device_fd(fd, ret_dev);
*ret_dev = makedev(sxa.sx.stx_dev_major, sxa.sx.stx_dev_minor);
return 0;