return 0; /* plain directory */
}
-int btrfs_subvol_set_read_only_fd(int fd, bool b) {
+int btrfs_subvol_set_read_only_at(int dir_fd, const char *path, bool b) {
+ _cleanup_close_ int fd = -EBADF;
uint64_t flags, nflags;
struct stat st;
- assert(fd >= 0);
+ assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
+
+ fd = xopenat(dir_fd, path, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY, /* xopen_flags = */ 0, /* mode = */ 0);
+ if (fd < 0)
+ return fd;
if (fstat(fd, &st) < 0)
return -errno;
return RET_NERRNO(ioctl(fd, BTRFS_IOC_SUBVOL_SETFLAGS, &nflags));
}
-int btrfs_subvol_set_read_only(const char *path, bool b) {
- _cleanup_close_ int fd = -EBADF;
-
- fd = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
- if (fd < 0)
- return -errno;
-
- return btrfs_subvol_set_read_only_fd(fd, b);
-}
-
int btrfs_subvol_get_read_only_fd(int fd) {
uint64_t flags;
struct stat st;
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);
+int btrfs_subvol_set_read_only_at(int dir_fd, const char *path, bool b);
+static inline int btrfs_subvol_set_read_only_fd(int fd, bool b) {
+ return btrfs_subvol_set_read_only_at(fd, NULL, b);
+}
+static inline int btrfs_subvol_set_read_only(const char *path, bool b) {
+ return btrfs_subvol_set_read_only_at(AT_FDCWD, path, b);
+}
+
int btrfs_subvol_get_read_only_fd(int fd);
int btrfs_subvol_get_id(int fd, const char *subvolume, uint64_t *ret);