From: Daan De Meyer Date: Thu, 30 Mar 2023 08:39:53 +0000 (+0200) Subject: btrfs-util: Add btrfs_get_block_device_at() X-Git-Tag: v254-rc1~837^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c706b27f40c0fc1b433a8742b2273cc453de2e1d;p=thirdparty%2Fsystemd.git 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(). --- diff --git a/src/shared/btrfs-util.c b/src/shared/btrfs-util.c index c6840575415..2789364c98f 100644 --- a/src/shared/btrfs-util.c +++ b/src/shared/btrfs-util.c @@ -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 diff --git a/src/shared/btrfs-util.h b/src/shared/btrfs-util.h index 080d5a607d8..75a8ed85490 100644 --- a/src/shared/btrfs-util.h +++ b/src/shared/btrfs-util.h @@ -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); diff --git a/src/shared/find-esp.c b/src/shared/find-esp.c index f6abe51de5f..c6ef4ec87aa 100644 --- a/src/shared/find-esp.c +++ b/src/shared/find-esp.c @@ -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;