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...
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user