mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 09:04:39 +02:00
btrfs: add helper for recording simple quota deltas
Rather than re-computing shared/exclusive ownership based on backrefs and walking roots for implicit backrefs, simple quotas does an increment when creating an extent and a decrement when deleting it. Add the API for the extent item code to use to track those events. Signed-off-by: Boris Burkov <boris@bur.io> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
6ed05643dd
commit
1e0e9d5771
|
|
@ -4586,3 +4586,49 @@ void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans)
|
||||||
}
|
}
|
||||||
*root = RB_ROOT;
|
*root = RB_ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int btrfs_record_squota_delta(struct btrfs_fs_info *fs_info,
|
||||||
|
struct btrfs_squota_delta *delta)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct btrfs_qgroup *qgroup;
|
||||||
|
struct btrfs_qgroup *qg;
|
||||||
|
LIST_HEAD(qgroup_list);
|
||||||
|
u64 root = delta->root;
|
||||||
|
u64 num_bytes = delta->num_bytes;
|
||||||
|
const int sign = (delta->is_inc ? 1 : -1);
|
||||||
|
|
||||||
|
if (btrfs_qgroup_mode(fs_info) != BTRFS_QGROUP_MODE_SIMPLE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!is_fstree(root))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
spin_lock(&fs_info->qgroup_lock);
|
||||||
|
qgroup = find_qgroup_rb(fs_info, root);
|
||||||
|
if (!qgroup) {
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
qgroup_iterator_add(&qgroup_list, qgroup);
|
||||||
|
list_for_each_entry(qg, &qgroup_list, iterator) {
|
||||||
|
struct btrfs_qgroup_list *glist;
|
||||||
|
|
||||||
|
qg->excl += num_bytes * sign;
|
||||||
|
qg->rfer += num_bytes * sign;
|
||||||
|
qgroup_dirty(fs_info, qg);
|
||||||
|
|
||||||
|
list_for_each_entry(glist, &qg->groups, next_group)
|
||||||
|
qgroup_iterator_add(&qgroup_list, glist->group);
|
||||||
|
}
|
||||||
|
qgroup_iterator_clean(&qgroup_list);
|
||||||
|
|
||||||
|
out:
|
||||||
|
spin_unlock(&fs_info->qgroup_lock);
|
||||||
|
if (!ret && delta->rsv_bytes)
|
||||||
|
btrfs_qgroup_free_refroot(fs_info, root, delta->rsv_bytes,
|
||||||
|
BTRFS_QGROUP_RSV_DATA);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,19 @@ struct btrfs_qgroup {
|
||||||
struct kobject kobj;
|
struct kobject kobj;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct btrfs_squota_delta {
|
||||||
|
/* The fstree root this delta counts against. */
|
||||||
|
u64 root;
|
||||||
|
/* The number of bytes in the extent being counted. */
|
||||||
|
u64 num_bytes;
|
||||||
|
/* The number of bytes reserved for this extent. */
|
||||||
|
u64 rsv_bytes;
|
||||||
|
/* Whether we are using or freeing the extent. */
|
||||||
|
bool is_inc;
|
||||||
|
/* Whether the extent is data or metadata. */
|
||||||
|
bool is_data;
|
||||||
|
};
|
||||||
|
|
||||||
static inline u64 btrfs_qgroup_subvolid(u64 qgroupid)
|
static inline u64 btrfs_qgroup_subvolid(u64 qgroupid)
|
||||||
{
|
{
|
||||||
return (qgroupid & ((1ULL << BTRFS_QGROUP_LEVEL_SHIFT) - 1));
|
return (qgroupid & ((1ULL << BTRFS_QGROUP_LEVEL_SHIFT) - 1));
|
||||||
|
|
@ -407,5 +420,7 @@ int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans,
|
||||||
struct btrfs_root *root, struct extent_buffer *eb);
|
struct btrfs_root *root, struct extent_buffer *eb);
|
||||||
void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans);
|
void btrfs_qgroup_destroy_extent_records(struct btrfs_transaction *trans);
|
||||||
bool btrfs_check_quota_leak(struct btrfs_fs_info *fs_info);
|
bool btrfs_check_quota_leak(struct btrfs_fs_info *fs_info);
|
||||||
|
int btrfs_record_squota_delta(struct btrfs_fs_info *fs_info,
|
||||||
|
struct btrfs_squota_delta *delta);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user