]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- added some btrfs qgroup functions
authorArvin Schnell <aschnell@suse.de>
Tue, 29 Mar 2016 10:43:32 +0000 (12:43 +0200)
committerArvin Schnell <aschnell@suse.de>
Tue, 29 Mar 2016 10:43:32 +0000 (12:43 +0200)
snapper/BtrfsUtils.cc
snapper/BtrfsUtils.h

index 1e30afbfbc8f6fc0c67cbf818814594afb3808e7..bd2d87cf417b287930de024d47dfee3113d62d93 100644 (file)
@@ -280,6 +280,54 @@ namespace snapper
 
 #ifdef ENABLE_BTRFS_QUOTA
 
+       void
+       quota_enable(int fd)
+       {
+            struct btrfs_ioctl_quota_ctl_args args;
+            memset(&args, 0, sizeof(args));
+            args.cmd = BTRFS_QUOTA_CTL_ENABLE;
+
+            if (ioctl(fd, BTRFS_IOC_QUOTA_CTL, &args) < 0)
+                throw runtime_error_with_errno("ioctl(BTRFS_IOC_QUOTA_CTL) failed", errno);
+       }
+
+
+       void
+       quota_disable(int fd)
+       {
+            struct btrfs_ioctl_quota_ctl_args args;
+            memset(&args, 0, sizeof(args));
+            args.cmd = BTRFS_QUOTA_CTL_DISABLE;
+
+            if (ioctl(fd, BTRFS_IOC_QUOTA_CTL, &args) < 0)
+                throw runtime_error_with_errno("ioctl(BTRFS_IOC_QUOTA_CTL) failed", errno);
+       }
+
+
+       void
+       quota_rescan(int fd)
+       {
+           struct btrfs_ioctl_quota_rescan_args args;
+           memset(&args, 0, sizeof(args));
+
+           if (ioctl(fd, BTRFS_IOC_QUOTA_RESCAN, &args) < 0)
+               throw runtime_error_with_errno("ioctl(BTRFS_IOC_QUOTA_RESCAN) failed", errno);
+
+           while (true)
+           {
+               sleep(1);
+
+               memset(&args, 0, sizeof(args));
+
+               if (ioctl(fd, BTRFS_IOC_QUOTA_RESCAN_STATUS, &args) < 0)
+                   throw runtime_error_with_errno("ioctl(BTRFS_IOC_QUOTA_STATUS) failed", errno);
+
+               if (!args.flags)
+                   break;
+           }
+       }
+
+
        qgroup_t
        calc_qgroup(uint64_t level, subvolid_t id)
        {
@@ -364,31 +412,52 @@ namespace snapper
        }
 
 
-       void
-       quota_rescan(int fd)
+       QGroupUsage
+       qgroup_query_usage(int fd, qgroup_t qgroup)
        {
-           struct btrfs_ioctl_quota_rescan_args args;
+           struct btrfs_ioctl_search_args args;
            memset(&args, 0, sizeof(args));
 
-           if (ioctl(fd, BTRFS_IOC_QUOTA_RESCAN, &args) < 0)
-               throw runtime_error_with_errno("ioctl(BTRFS_IOC_QUOTA_RESCAN) failed", errno);
+           struct btrfs_ioctl_search_key* sk = &args.key;
+           sk->tree_id = BTRFS_QUOTA_TREE_OBJECTID;
+           sk->min_objectid = 0;
+           sk->max_objectid = 0;
+           sk->min_offset = qgroup;
+           sk->max_offset = qgroup;
+           sk->min_transid = 0;
+           sk->max_transid = (u64) -1;
+           sk->min_type = BTRFS_QGROUP_INFO_KEY;
+           sk->max_type = BTRFS_QGROUP_INFO_KEY;
+           sk->nr_items = 16;
 
-           while (true)
-           {
-               sleep(1);
+           if (ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args) < 0)
+               throw runtime_error_with_errno("ioctl(BTRFS_IOC_TREE_SEARCH) failed", errno);
 
-               memset(&args, 0, sizeof(args));
+           if (sk->nr_items != 1)
+               throw std::runtime_error("sk->qnr_items != 1");
 
-               if (ioctl(fd, BTRFS_IOC_QUOTA_RESCAN_STATUS, &args) < 0)
-                   throw runtime_error_with_errno("ioctl(BTRFS_IOC_QUOTA_STATUS) failed", errno);
+           struct btrfs_ioctl_search_header* sh = (struct btrfs_ioctl_search_header*)(args.buf);
+           if (sh->offset != qgroup)
+               throw std::runtime_error("sh->offset != qgroup");
 
-               if (!args.flags)
-                   break;
-           }
+           if (sh->type != BTRFS_QGROUP_INFO_KEY)
+               throw std::runtime_error("sh->type != BTRFS_QGROUP_INFO_KEY");
+
+           struct btrfs_qgroup_info_item info;
+           memcpy(&info, (struct btrfs_qgroup_info_item*)(args.buf + sizeof(*sh)), sizeof(info));
+
+           QGroupUsage qgroup_usage;
+           qgroup_usage.referenced = le64_to_cpu(info.referenced);
+           qgroup_usage.referenced_compressed = le64_to_cpu(info.referenced_compressed);
+           qgroup_usage.exclusive = le64_to_cpu(info.exclusive);
+           qgroup_usage.exclusive_compressed = le64_to_cpu(info.exclusive_compressed);
+
+           return qgroup_usage;
        }
 
 #endif
 
+
        void
        sync(int fd)
        {
index 230cadc3e0b39dcb6ca8110cf535afb74110555a..f76b130aa6eb9f085063c3104f14d8a8d0c4ef86 100644 (file)
@@ -24,6 +24,7 @@
 #define SNAPPER_BTRFS_UTILS_H
 
 
+#include <stdint.h>
 #include <string>
 
 
@@ -57,6 +58,11 @@ namespace snapper
        string get_subvolume(int fd, subvolid_t id);
        subvolid_t get_id(int fd);
 
+       void quota_enable(int fd);
+       void quota_disable(int fd);
+
+       void quota_rescan(int fd);
+
        qgroup_t calc_qgroup(uint64_t level, subvolid_t id);
        qgroup_t parse_qgroup(const string& str);
 
@@ -66,7 +72,18 @@ namespace snapper
        void qgroup_assign(int fd, qgroup_t src, qgroup_t dst);
        void qgroup_remove(int fd, qgroup_t src, qgroup_t dst);
 
-       void quota_rescan(int fd);
+       struct QGroupUsage
+       {
+           QGroupUsage() : referenced(0), referenced_compressed(0), exclusive(0),
+                           exclusive_compressed(0) {}
+
+           uint64_t referenced;
+           uint64_t referenced_compressed;
+           uint64_t exclusive;
+           uint64_t exclusive_compressed;
+       };
+
+       QGroupUsage qgroup_query_usage(int fd, qgroup_t qgroup);
 
        void sync(int fd);