#include "alloc-util.h"
#include "blockdev-util.h"
#include "btrfs-util.h"
+#include "chase.h"
#include "chattr-util.h"
#include "copy.h"
#include "fd-util.h"
return 0;
}
-int btrfs_subvol_remove(const char *path, BtrfsRemoveFlags flags) {
+int btrfs_subvol_remove_at(int dir_fd, const char *path, BtrfsRemoveFlags flags) {
_cleanup_free_ char *subvolume = NULL;
_cleanup_close_ int fd = -EBADF;
int r;
assert(path);
- r = extract_subvolume_name(path, &subvolume);
- if (r < 0)
- return r;
-
- fd = open_parent(path, O_CLOEXEC, 0);
+ fd = chase_and_openat(dir_fd, path, CHASE_PARENT|CHASE_EXTRACT_FILENAME, O_CLOEXEC, &subvolume);
if (fd < 0)
return fd;
- return subvol_remove_children(fd, subvolume, 0, flags);
-}
+ r = validate_subvolume_name(subvolume);
+ if (r < 0)
+ return r;
-int btrfs_subvol_remove_fd(int fd, const char *subvolume, BtrfsRemoveFlags flags) {
return subvol_remove_children(fd, subvolume, 0, flags);
}
return btrfs_subvol_snapshot_full(old_path, new_path, flags, NULL, NULL, NULL);
}
-int btrfs_subvol_remove(const char *path, BtrfsRemoveFlags flags);
-int btrfs_subvol_remove_fd(int fd, const char *subvolume, BtrfsRemoveFlags flags);
+int btrfs_subvol_remove_at(int dir_fd, const char *path, BtrfsRemoveFlags flags);
+static inline int btrfs_subvol_remove(const char *path, BtrfsRemoveFlags flags) {
+ return btrfs_subvol_remove_at(AT_FDCWD, path, flags);
+}
int btrfs_subvol_set_read_only_fd(int fd, bool b);
int btrfs_subvol_set_read_only(const char *path, bool b);
if ((flags & REMOVE_SUBVOLUME) && btrfs_might_be_subvol(&st)) {
/* This could be a subvolume, try to remove it */
- r = btrfs_subvol_remove_fd(fd, fname, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
+ r = btrfs_subvol_remove_at(fd, fname, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
if (r < 0) {
if (!IN_SET(r, -ENOTTY, -EINVAL))
return r;