diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/btrfs-util.c | 21 | ||||
-rw-r--r-- | src/shared/btrfs-util.h | 1 | ||||
-rw-r--r-- | src/shared/util.h | 9 |
3 files changed, 25 insertions, 6 deletions
diff --git a/src/shared/btrfs-util.c b/src/shared/btrfs-util.c index 492d7fc777..d685b3ecbd 100644 --- a/src/shared/btrfs-util.c +++ b/src/shared/btrfs-util.c @@ -84,18 +84,18 @@ int btrfs_is_snapshot(int fd) { struct stat st; struct statfs sfs; - if (fstatfs(fd, &sfs) < 0) + /* On btrfs subvolumes always have the inode 256 */ + + if (fstat(fd, &st) < 0) return -errno; - if (!F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) + if (!S_ISDIR(st.st_mode) || st.st_ino != 256) return 0; - if (fstat(fd, &st) < 0) + if (fstatfs(fd, &sfs) < 0) return -errno; - /* On btrfs subvolumes always have the inode 256 */ - - return S_ISDIR(st.st_mode) && st.st_ino == 256; + return F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC); } int btrfs_subvol_snapshot(const char *old_path, const char *new_path, bool read_only, bool fallback_copy) { @@ -232,6 +232,15 @@ int btrfs_subvol_read_only(const char *path, bool b) { return 0; } +int btrfs_subvol_is_read_only_fd(int fd) { + uint64_t flags; + + if (ioctl(fd, BTRFS_IOC_SUBVOL_GETFLAGS, &flags) < 0) + return -errno; + + return !!(flags & BTRFS_SUBVOL_RDONLY); +} + int btrfs_reflink(int infd, int outfd) { int r; diff --git a/src/shared/btrfs-util.h b/src/shared/btrfs-util.h index 28dbeb4e27..c8f798b6a6 100644 --- a/src/shared/btrfs-util.h +++ b/src/shared/btrfs-util.h @@ -28,6 +28,7 @@ int btrfs_subvol_make(const char *path); int btrfs_subvol_remove(const char *path); int btrfs_subvol_snapshot(const char *old_path, const char *new_path, bool read_only, bool fallback_copy); int btrfs_subvol_read_only(const char *path, bool b); +int btrfs_subvol_is_read_only_fd(int fd); int btrfs_reflink(int infd, int outfd); diff --git a/src/shared/util.h b/src/shared/util.h index 96b8c1bcc0..e783ec6cdb 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -775,6 +775,15 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *root continue; \ else +#define FOREACH_DIRENT_ALL(de, d, on_error) \ + for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \ + if (!de) { \ + if (errno > 0) { \ + on_error; \ + } \ + break; \ + } else + static inline void *mempset(void *s, int c, size_t n) { memset(s, c, n); return (uint8_t*)s + n; |