btrfs-util: Add btrfs_get_block_device_at()

Let's make btrfs_get_block_device_fd() more generic by renaming it
to btrfs_get_block_device_at() so it can operate on only paths, dir_fd
and path, or only on fd by using xopenat().
This commit is contained in:
Daan De Meyer
2023-04-01 14:25:30 +02:00
parent 86c20937c2
commit c706b27f40
3 changed files with 17 additions and 34 deletions
+8 -20
View File
@@ -247,16 +247,17 @@ int btrfs_clone_range(int infd, uint64_t in_offset, int outfd, uint64_t out_offs
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, &regfd);
fd = xopenat(dir_fd, path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY, 0);
if (fd < 0)
return fd;
@@ -271,7 +272,7 @@ int btrfs_get_block_device_fd(int fd, dev_t *dev) {
/* We won't do this for btrfs RAID */
if (fsi.num_devices != 1) {
*dev = 0;
*ret = 0;
return 0;
}
@@ -306,26 +307,13 @@ int btrfs_get_block_device_fd(int fd, dev_t *dev) {
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
+7 -2
View File
@@ -49,8 +49,13 @@ int btrfs_is_subvol(const char *path);
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);
+2 -12
View File
@@ -327,18 +327,8 @@ success:
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;