btrfs: drop O_PATH from dir_fd passed to btrfs_subvol_make() if needed

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 e54c79ccc2

Fixes: e54c79ccc2
This commit is contained in:
Lennart Poettering
2023-08-16 14:29:20 +02:00
parent 8d6791d2aa
commit f5254d0047
+12 -5
View 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;
}