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:
+8
-20
@@ -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, ®fd);
|
||||
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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user