summaryrefslogtreecommitdiff
path: root/src/basic/btrfs-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic/btrfs-util.c')
-rw-r--r--src/basic/btrfs-util.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c
index 4c90bc0c80..be40dc5702 100644
--- a/src/basic/btrfs-util.c
+++ b/src/basic/btrfs-util.c
@@ -105,7 +105,7 @@ int btrfs_is_filesystem(int fd) {
return F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC);
}
-int btrfs_is_subvol(int fd) {
+int btrfs_is_subvol_fd(int fd) {
struct stat st;
assert(fd >= 0);
@@ -121,6 +121,18 @@ int btrfs_is_subvol(int fd) {
return btrfs_is_filesystem(fd);
}
+int btrfs_is_subvol(const char *path) {
+ _cleanup_close_ int fd = -1;
+
+ assert(path);
+
+ fd = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
+ if (fd < 0)
+ return -errno;
+
+ return btrfs_is_subvol_fd(fd);
+}
+
int btrfs_subvol_make(const char *path) {
struct btrfs_ioctl_vol_args args = {};
_cleanup_close_ int fd = -1;
@@ -575,8 +587,12 @@ int btrfs_qgroup_get_quota_fd(int fd, uint64_t qgroupid, BtrfsQuotaInfo *ret) {
unsigned i;
args.key.nr_items = 256;
- if (ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args) < 0)
+ if (ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args) < 0) {
+ if (errno == ENOENT) /* quota tree is missing: quota disabled */
+ break;
+
return -errno;
+ }
if (args.key.nr_items <= 0)
break;
@@ -1006,6 +1022,10 @@ static int qgroup_create_or_destroy(int fd, bool b, uint64_t qgroupid) {
for (c = 0;; c++) {
if (ioctl(fd, BTRFS_IOC_QGROUP_CREATE, &args) < 0) {
+ /* If quota is not enabled, we get EINVAL. Turn this into a recognizable error */
+ if (errno == EINVAL)
+ return -ENOPROTOOPT;
+
if (errno == EBUSY && c < 10) {
(void) btrfs_quota_scan_wait(fd);
continue;
@@ -1335,8 +1355,12 @@ int btrfs_qgroup_copy_limits(int fd, uint64_t old_qgroupid, uint64_t new_qgroupi
unsigned i;
args.key.nr_items = 256;
- if (ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args) < 0)
+ if (ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args) < 0) {
+ if (errno == ENOENT) /* quota tree missing: quota is not enabled, hence nothing to copy */
+ break;
+
return -errno;
+ }
if (args.key.nr_items <= 0)
break;
@@ -1411,12 +1435,16 @@ static int copy_quota_hierarchy(int fd, uint64_t old_subvol_id, uint64_t new_sub
return n_old_qgroups;
r = btrfs_subvol_get_parent(fd, old_subvol_id, &old_parent_id);
- if (r < 0)
+ if (r == -ENXIO)
+ /* We have no parent, hence nothing to copy. */
+ n_old_parent_qgroups = 0;
+ else if (r < 0)
return r;
-
- n_old_parent_qgroups = btrfs_qgroup_find_parents(fd, old_parent_id, &old_parent_qgroups);
- if (n_old_parent_qgroups < 0)
- return n_old_parent_qgroups;
+ else {
+ n_old_parent_qgroups = btrfs_qgroup_find_parents(fd, old_parent_id, &old_parent_qgroups);
+ if (n_old_parent_qgroups < 0)
+ return n_old_parent_qgroups;
+ }
for (i = 0; i < n_old_qgroups; i++) {
uint64_t id;
@@ -1670,7 +1698,7 @@ int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlag
assert(old_fd >= 0);
assert(new_path);
- r = btrfs_is_subvol(old_fd);
+ r = btrfs_is_subvol_fd(old_fd);
if (r < 0)
return r;
if (r == 0) {
@@ -1766,8 +1794,12 @@ int btrfs_qgroup_find_parents(int fd, uint64_t qgroupid, uint64_t **ret) {
unsigned i;
args.key.nr_items = 256;
- if (ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args) < 0)
+ if (ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args) < 0) {
+ if (errno == ENOENT) /* quota tree missing: quota is disabled */
+ break;
+
return -errno;
+ }
if (args.key.nr_items <= 0)
break;
@@ -1852,7 +1884,7 @@ int btrfs_subvol_auto_qgroup_fd(int fd, uint64_t subvol_id, bool insert_intermed
*/
if (subvol_id == 0) {
- r = btrfs_is_subvol(fd);
+ r = btrfs_is_subvol_fd(fd);
if (r < 0)
return r;
if (!r)
@@ -1869,14 +1901,19 @@ int btrfs_subvol_auto_qgroup_fd(int fd, uint64_t subvol_id, bool insert_intermed
if (n > 0) /* already parent qgroups set up, let's bail */
return 0;
+ qgroups = mfree(qgroups);
+
r = btrfs_subvol_get_parent(fd, subvol_id, &parent_subvol);
- if (r < 0)
+ if (r == -ENXIO)
+ /* No parent, hence no qgroup memberships */
+ n = 0;
+ else if (r < 0)
return r;
-
- qgroups = mfree(qgroups);
- n = btrfs_qgroup_find_parents(fd, parent_subvol, &qgroups);
- if (n < 0)
- return n;
+ else {
+ n = btrfs_qgroup_find_parents(fd, parent_subvol, &qgroups);
+ if (n < 0)
+ return n;
+ }
if (insert_intermediary_qgroup) {
uint64_t lowest = 256, new_qgroupid;