From: Arvin Schnell Date: Thu, 24 Mar 2016 13:38:44 +0000 (+0100) Subject: - added some btrfs qgroup functions X-Git-Tag: v0.3.3~17^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0e83ec1ded62ab3d36f28c8b938ddc747028048d;p=thirdparty%2Fsnapper.git - added some btrfs qgroup functions --- diff --git a/snapper/Btrfs.cc b/snapper/Btrfs.cc index 7029e66c..b30f49d3 100644 --- a/snapper/Btrfs.cc +++ b/snapper/Btrfs.cc @@ -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 } diff --git a/snapper/BtrfsUtils.cc b/snapper/BtrfsUtils.cc index bf737fb1..1e30afbf 100644 --- a/snapper/BtrfsUtils.cc +++ b/snapper/BtrfsUtils.cc @@ -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) diff --git a/snapper/BtrfsUtils.h b/snapper/BtrfsUtils.h index 5e9eb494..230cadc3 100644 --- a/snapper/BtrfsUtils.h +++ b/snapper/BtrfsUtils.h @@ -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);