]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
btrfs: drop O_PATH from dir_fd passed to btrfs_subvol_make() if needed
authorLennart Poettering <lennart@poettering.net>
Wed, 16 Aug 2023 10:11:06 +0000 (12:11 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 16 Aug 2023 12:29:20 +0000 (14:29 +0200)
Let's make sure btrfs_subvol_make() can operate on O_PATH fds, just like
mkdirat().

Fixes a bunch of tmpfiles errors at boot if we try to create btrfs
subvols, introduced by e54c79ccc2e90a375640815b05f28ec22664e44c

Fixes: e54c79ccc2e90a375640815b05f28ec22664e44c
src/basic/btrfs.c

index a13fec4873fcc26f532e4dd633cf09c5a6ca19c2..78957a1d2b82f419e347d739e18a2c2a8baa0464 100644 (file)
@@ -40,7 +40,7 @@ static int extract_subvolume_name(const char *path, char **ret) {
 
 int btrfs_subvol_make(int dir_fd, const char *path) {
         struct btrfs_ioctl_vol_args args = {};
-        _cleanup_free_ char *subvolume = NULL;
+        _cleanup_free_ char *subvolume = NULL, *parent = NULL;
         _cleanup_close_ int fd = -EBADF;
         int r;
 
@@ -51,11 +51,18 @@ int btrfs_subvol_make(int dir_fd, const char *path) {
         if (r < 0)
                 return r;
 
-        r = path_extract_directory(path, NULL);
-        if (r >= 0) {
-                fd = open_parent_at(dir_fd, path, O_RDONLY|O_CLOEXEC|O_CLOEXEC, 0);
+        r = path_extract_directory(path, &parent);
+        if (r < 0) {
+                if (r != -EDESTADDRREQ) /* Propagate error, unless only a filename was specified, which is OK */
+                        return r;
+
+                dir_fd = fd_reopen_condition(dir_fd, O_CLOEXEC, O_PATH, &fd); /* drop O_PATH if it is set */
+                if (dir_fd < 0)
+                        return dir_fd;
+        } else {
+                fd = openat(dir_fd, parent, O_DIRECTORY|O_RDONLY|O_CLOEXEC, 0);
                 if (fd < 0)
-                        return fd;
+                        return -errno;
 
                 dir_fd = fd;
         }