]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- added some btrfs qgroup functions
authorArvin Schnell <aschnell@suse.de>
Thu, 24 Mar 2016 13:38:44 +0000 (14:38 +0100)
committerArvin Schnell <aschnell@suse.de>
Thu, 24 Mar 2016 13:38:44 +0000 (14:38 +0100)
snapper/Btrfs.cc
snapper/BtrfsUtils.cc
snapper/BtrfsUtils.h

index 7029e66cbfd40889f5dbbefa35efbe8d1dbee36c..b30f49d31055af72e5eddecab998e520298443c3 100644 (file)
@@ -83,12 +83,14 @@ namespace snapper
     void
     Btrfs::evalConfigInfo(const ConfigInfo& config_info)
     {
+#ifdef ENABLE_BTRFS_QUOTA
+
        string qgroup_str;
        if (config_info.getValue("QGROUP", qgroup_str) && !qgroup_str.empty())
        {
            try
            {
-               qgroup = make_qgroup(qgroup_str);
+               qgroup = parse_qgroup(qgroup_str);
            }
            catch (const runtime_error& e)
            {
@@ -96,6 +98,8 @@ namespace snapper
                throw InvalidConfigException();
            }
        }
+
+#endif
     }
 
 
index bf737fb1a59e488d2bbd2d29e56d2d45ac5a9244..1e30afbfbc8f6fc0c67cbf818814594afb3808e7 100644 (file)
@@ -126,6 +126,7 @@ namespace snapper
            strncpy(args_v2.name, name.c_str(), sizeof(args_v2.name) - 1);
 
 #ifdef ENABLE_BTRFS_QUOTA
+
            if (qgroup != no_qgroup)
            {
                size_t size = sizeof(btrfs_qgroup_inherit) + sizeof(((btrfs_qgroup_inherit*) 0)->qgroups[0]);
@@ -141,6 +142,7 @@ namespace snapper
                args_v2.size = size;
                args_v2.qgroup_inherit = inherit;
            }
+
 #endif
 
            if (ioctl(fddst, BTRFS_IOC_SNAP_CREATE_V2, &args_v2) == 0)
@@ -249,18 +251,44 @@ namespace snapper
            return args.treeid;
        }
 
+
+       bool
+       does_subvolume_exist(int fd, subvolid_t subvolid)
+       {
+           struct btrfs_ioctl_search_args args;
+           struct btrfs_ioctl_search_key* sk = &args.key;
+
+           sk->tree_id = BTRFS_ROOT_TREE_OBJECTID;
+           sk->min_objectid = subvolid;
+           sk->max_objectid = subvolid;
+           sk->min_type = BTRFS_ROOT_ITEM_KEY;
+           sk->max_type = BTRFS_ROOT_ITEM_KEY;
+           sk->min_offset = 0;
+           sk->max_offset = (u64) -1;
+           sk->min_transid = 0;
+           sk->max_transid = (u64) -1;
+           sk->nr_items = 1;
+
+           if (ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args) != 0)
+               throw runtime_error_with_errno("ioctl(BTRFS_IOC_TREE_SEARCH) failed", errno);
+
+           return sk->nr_items == 0;
+       }
+
 #endif
 
 
+#ifdef ENABLE_BTRFS_QUOTA
+
        qgroup_t
-       make_qgroup(uint64_t level, subvolid_t id)
+       calc_qgroup(uint64_t level, subvolid_t id)
        {
            return (level << 48) | id;
        }
 
 
        qgroup_t
-       make_qgroup(const string& str)
+       parse_qgroup(const string& str)
        {
            string::size_type pos = str.find('/');
            if (pos == string::npos)
@@ -278,37 +306,88 @@ namespace snapper
            if (b.fail() || !b.eof())
                throw std::runtime_error("parsing qgroup failed");
 
-           return make_qgroup(level, id);
+           return calc_qgroup(level, id);
        }
 
 
-#ifdef HAVE_LIBBTRFS
+       void
+       qgroup_create(int fd, qgroup_t qgroup)
+       {
+           struct btrfs_ioctl_qgroup_create_args args;
+           memset(&args, 0, sizeof(args));
+           args.create = 1;
+           args.qgroupid = qgroup;
 
-       bool
-       does_subvolume_exist(int fd, subvolid_t subvolid)
+           if (ioctl(fd, BTRFS_IOC_QGROUP_CREATE, &args) != 0)
+               throw runtime_error_with_errno("ioctl(BTRFS_IOC_QGROUP_CREATE) failed", errno);
+       }
+
+
+       void
+       qgroup_destroy(int fd, qgroup_t qgroup)
        {
-           struct btrfs_ioctl_search_args args;
-           struct btrfs_ioctl_search_key* sk = &args.key;
+           struct btrfs_ioctl_qgroup_create_args args;
+           memset(&args, 0, sizeof(args));
+           args.create = 0;
+           args.qgroupid = qgroup;
 
-           sk->tree_id = BTRFS_ROOT_TREE_OBJECTID;
-           sk->min_objectid = subvolid;
-           sk->max_objectid = subvolid;
-           sk->min_type = BTRFS_ROOT_ITEM_KEY;
-           sk->max_type = BTRFS_ROOT_ITEM_KEY;
-           sk->min_offset = 0;
-           sk->max_offset = (u64) -1;
-           sk->min_transid = 0;
-           sk->max_transid = (u64) -1;
-           sk->nr_items = 1;
+           if (ioctl(fd, BTRFS_IOC_QGROUP_CREATE, &args) != 0)
+               throw runtime_error_with_errno("ioctl(BTRFS_IOC_QGROUP_CREATE) failed", errno);
+       }
 
-           if (ioctl(fd, BTRFS_IOC_TREE_SEARCH, &args) != 0)
-               throw runtime_error_with_errno("ioctl(BTRFS_IOC_TREE_SEARCH) failed", errno);
 
-           return sk->nr_items == 0;
+       void
+       qgroup_assign(int fd, qgroup_t src, qgroup_t dst)
+       {
+           struct btrfs_ioctl_qgroup_assign_args args;
+           memset(&args, 0, sizeof(args));
+           args.assign = 1;
+           args.src = src;
+           args.dst = dst;
+
+           if (ioctl(fd, BTRFS_IOC_QGROUP_ASSIGN, &args) != 0)
+               throw runtime_error_with_errno("ioctl(BTRFS_IOC_QGROUP_ASSIGN) failed", errno);
        }
 
-#endif
 
+       void
+       qgroup_remove(int fd, qgroup_t src, qgroup_t dst)
+       {
+           struct btrfs_ioctl_qgroup_assign_args args;
+           memset(&args, 0, sizeof(args));
+           args.assign = 0;
+           args.src = src;
+           args.dst = dst;
+
+           if (ioctl(fd, BTRFS_IOC_QGROUP_ASSIGN, &args) != 0)
+               throw runtime_error_with_errno("ioctl(BTRFS_IOC_QGROUP_ASSIGN) 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;
+           }
+       }
+
+#endif
 
        void
        sync(int fd)
index 5e9eb49445b5262a614f0ab4f7c231fae82c41de..230cadc3e0b39dcb6ca8110cf535afb74110555a 100644 (file)
@@ -57,8 +57,16 @@ namespace snapper
        string get_subvolume(int fd, subvolid_t id);
        subvolid_t get_id(int fd);
 
-       qgroup_t make_qgroup(uint64_t level, subvolid_t id);
-       qgroup_t make_qgroup(const string& str);
+       qgroup_t calc_qgroup(uint64_t level, subvolid_t id);
+       qgroup_t parse_qgroup(const string& str);
+
+       void qgroup_create(int fd, qgroup_t qgroup);
+       void qgroup_destroy(int fd, qgroup_t qgroup);
+
+       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);
 
        void sync(int fd);