summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-08-06 19:32:00 +0200
committerLennart Poettering <lennart@poettering.net>2018-08-08 11:59:39 +0200
commit2e6e61688748473c4230ca49b402aea2bec9b8ab (patch)
treeec550a0636f6349e760f1cd097a1cd80ba130f9b
parent713998cfc8c2f08d096edf047bc0707c3e53286d (diff)
downloadsystemd-2e6e61688748473c4230ca49b402aea2bec9b8ab.tar.gz
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...
-rw-r--r--src/basic/btrfs-util.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c
index abd34824e7..376844b7b1 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)