]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
btrfs-util: Add btrfs_get_block_device_at()
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Thu, 30 Mar 2023 08:39:53 +0000 (10:39 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Sat, 1 Apr 2023 12:25:30 +0000 (14:25 +0200)
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().

src/shared/btrfs-util.c
src/shared/btrfs-util.h
src/shared/find-esp.c

index c68405754152805e825b2b40d64434beb60d6bf0..2789364c98fe84bbcd1b3f01e49a0e94f88ebaef 100644 (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
index 080d5a607d8d5c5e64a8deaa2f9aee85f4aee65a..75a8ed85490ec0f37fcbd9e0f048873b7e2d8e55 100644 (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);
index f6abe51de5f61f8511685cac9cb0dbd5b069607d..c6ef4ec87aae7212473df3dbdf71bbbc0e568a06 100644 (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;