From: Lennart Poettering Date: Mon, 6 Aug 2018 17:32:00 +0000 (+0200) Subject: btrfs-util: unfuck tmpfiles' subvol creation X-Git-Tag: v240~828^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2e6e61688748473c4230ca49b402aea2bec9b8ab;p=thirdparty%2Fsystemd.git btrfs-util: unfuck tmpfiles' subvol creation tmpfiles now passes an O_PATH fd to btrfs_subvol_make_fd() under the assumption it will accept it like mkdirat() does. So far this assumption was wrong, let's correct that. Without that tmpfiles' on btrfs file systems failed systematically... --- diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c index abd34824e7d..376844b7b17 100644 --- a/src/basic/btrfs-util.c +++ b/src/basic/btrfs-util.c @@ -118,6 +118,7 @@ int btrfs_is_subvol(const char *path) { int btrfs_subvol_make_fd(int fd, const char *subvolume) { struct btrfs_ioctl_vol_args args = {}; + _cleanup_close_ int real_fd = -1; int r; assert(subvolume); @@ -126,6 +127,20 @@ int btrfs_subvol_make_fd(int fd, const char *subvolume) { if (r < 0) return r; + r = fcntl(fd, F_GETFL); + if (r < 0) + return -errno; + if (FLAGS_SET(r, O_PATH)) { + /* An O_PATH fd was specified, let's convert here to a proper one, as btrfs ioctl's can't deal with + * O_PATH. */ + + real_fd = fd_reopen(fd, O_RDONLY|O_CLOEXEC|O_DIRECTORY); + if (real_fd < 0) + return real_fd; + + fd = real_fd; + } + strncpy(args.name, subvolume, sizeof(args.name)-1); if (ioctl(fd, BTRFS_IOC_SUBVOL_CREATE, &args) < 0)