|
|
|
@ -34,9 +34,21 @@ enum btrfs_qgroup_mode btrfs_qgroup_mode(struct btrfs_fs_info *fs_info)
|
|
|
|
|
{
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
|
|
|
return BTRFS_QGROUP_MODE_DISABLED;
|
|
|
|
|
if (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE)
|
|
|
|
|
return BTRFS_QGROUP_MODE_SIMPLE;
|
|
|
|
|
return BTRFS_QGROUP_MODE_FULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool btrfs_qgroup_enabled(struct btrfs_fs_info *fs_info)
|
|
|
|
|
{
|
|
|
|
|
return btrfs_qgroup_mode(fs_info) != BTRFS_QGROUP_MODE_DISABLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool btrfs_qgroup_full_accounting(struct btrfs_fs_info *fs_info)
|
|
|
|
|
{
|
|
|
|
|
return btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_FULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Helpers to access qgroup reservation
|
|
|
|
|
*
|
|
|
|
@ -350,6 +362,8 @@ int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid,
|
|
|
|
|
|
|
|
|
|
static void qgroup_mark_inconsistent(struct btrfs_fs_info *fs_info)
|
|
|
|
|
{
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_SIMPLE)
|
|
|
|
|
return;
|
|
|
|
|
fs_info->qgroup_flags |= (BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT |
|
|
|
|
|
BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN |
|
|
|
|
|
BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING);
|
|
|
|
@ -370,8 +384,9 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
|
|
|
|
|
int ret = 0;
|
|
|
|
|
u64 flags = 0;
|
|
|
|
|
u64 rescan_progress = 0;
|
|
|
|
|
bool simple;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_DISABLED)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
fs_info->qgroup_ulist = ulist_alloc(GFP_KERNEL);
|
|
|
|
@ -421,14 +436,14 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
|
|
|
|
|
"old qgroup version, quota disabled");
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
fs_info->qgroup_flags = btrfs_qgroup_status_flags(l, ptr);
|
|
|
|
|
simple = (fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE);
|
|
|
|
|
if (btrfs_qgroup_status_generation(l, ptr) !=
|
|
|
|
|
fs_info->generation) {
|
|
|
|
|
fs_info->generation && !simple) {
|
|
|
|
|
qgroup_mark_inconsistent(fs_info);
|
|
|
|
|
btrfs_err(fs_info,
|
|
|
|
|
"qgroup generation mismatch, marked as inconsistent");
|
|
|
|
|
}
|
|
|
|
|
fs_info->qgroup_flags = btrfs_qgroup_status_flags(l,
|
|
|
|
|
ptr);
|
|
|
|
|
rescan_progress = btrfs_qgroup_status_rescan(l, ptr);
|
|
|
|
|
goto next1;
|
|
|
|
|
}
|
|
|
|
@ -571,7 +586,7 @@ bool btrfs_check_quota_leak(struct btrfs_fs_info *fs_info)
|
|
|
|
|
struct rb_node *node;
|
|
|
|
|
bool ret = false;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_DISABLED)
|
|
|
|
|
return ret;
|
|
|
|
|
/*
|
|
|
|
|
* Since we're unmounting, there is no race and no need to grab qgroup
|
|
|
|
@ -970,7 +985,8 @@ out:
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
|
|
|
|
|
int btrfs_quota_enable(struct btrfs_fs_info *fs_info,
|
|
|
|
|
struct btrfs_ioctl_quota_ctl_args *quota_ctl_args)
|
|
|
|
|
{
|
|
|
|
|
struct btrfs_root *quota_root;
|
|
|
|
|
struct btrfs_root *tree_root = fs_info->tree_root;
|
|
|
|
@ -983,6 +999,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
|
|
|
|
|
struct btrfs_qgroup *prealloc = NULL;
|
|
|
|
|
struct btrfs_trans_handle *trans = NULL;
|
|
|
|
|
struct ulist *ulist = NULL;
|
|
|
|
|
const bool simple = (quota_ctl_args->cmd == BTRFS_QUOTA_CTL_ENABLE_SIMPLE_QUOTA);
|
|
|
|
|
int ret = 0;
|
|
|
|
|
int slot;
|
|
|
|
|
|
|
|
|
@ -1085,8 +1102,11 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info)
|
|
|
|
|
struct btrfs_qgroup_status_item);
|
|
|
|
|
btrfs_set_qgroup_status_generation(leaf, ptr, trans->transid);
|
|
|
|
|
btrfs_set_qgroup_status_version(leaf, ptr, BTRFS_QGROUP_STATUS_VERSION);
|
|
|
|
|
fs_info->qgroup_flags = BTRFS_QGROUP_STATUS_FLAG_ON |
|
|
|
|
|
BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
|
|
|
|
|
fs_info->qgroup_flags = BTRFS_QGROUP_STATUS_FLAG_ON;
|
|
|
|
|
if (simple)
|
|
|
|
|
fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE;
|
|
|
|
|
else
|
|
|
|
|
fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
|
|
|
|
|
btrfs_set_qgroup_status_flags(leaf, ptr, fs_info->qgroup_flags &
|
|
|
|
|
BTRFS_QGROUP_STATUS_FLAGS_MASK);
|
|
|
|
|
btrfs_set_qgroup_status_rescan(leaf, ptr, 0);
|
|
|
|
@ -1214,8 +1234,14 @@ out_add_root:
|
|
|
|
|
spin_lock(&fs_info->qgroup_lock);
|
|
|
|
|
fs_info->quota_root = quota_root;
|
|
|
|
|
set_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags);
|
|
|
|
|
if (simple)
|
|
|
|
|
btrfs_set_fs_incompat(fs_info, SIMPLE_QUOTA);
|
|
|
|
|
spin_unlock(&fs_info->qgroup_lock);
|
|
|
|
|
|
|
|
|
|
/* Skip rescan for simple qgroups. */
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_SIMPLE)
|
|
|
|
|
goto out_free_path;
|
|
|
|
|
|
|
|
|
|
ret = qgroup_rescan_init(fs_info, 0, 1);
|
|
|
|
|
if (!ret) {
|
|
|
|
|
qgroup_rescan_zero_tracking(fs_info);
|
|
|
|
@ -1330,6 +1356,7 @@ int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
|
|
|
|
|
quota_root = fs_info->quota_root;
|
|
|
|
|
fs_info->quota_root = NULL;
|
|
|
|
|
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
|
|
|
|
|
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_SIMPLE_MODE;
|
|
|
|
|
fs_info->qgroup_drop_subtree_thres = BTRFS_MAX_LEVEL;
|
|
|
|
|
spin_unlock(&fs_info->qgroup_lock);
|
|
|
|
|
|
|
|
|
@ -1810,6 +1837,9 @@ int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info,
|
|
|
|
|
struct btrfs_qgroup_extent_record *entry;
|
|
|
|
|
u64 bytenr = record->bytenr;
|
|
|
|
|
|
|
|
|
|
if (!btrfs_qgroup_full_accounting(fs_info))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
lockdep_assert_held(&delayed_refs->lock);
|
|
|
|
|
trace_btrfs_qgroup_trace_extent(fs_info, record);
|
|
|
|
|
|
|
|
|
@ -1863,6 +1893,8 @@ int btrfs_qgroup_trace_extent_post(struct btrfs_trans_handle *trans,
|
|
|
|
|
struct btrfs_backref_walk_ctx ctx = { 0 };
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (!btrfs_qgroup_full_accounting(trans->fs_info))
|
|
|
|
|
return 0;
|
|
|
|
|
/*
|
|
|
|
|
* We are always called in a context where we are already holding a
|
|
|
|
|
* transaction handle. Often we are called when adding a data delayed
|
|
|
|
@ -1931,8 +1963,7 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, u64 bytenr,
|
|
|
|
|
struct btrfs_delayed_ref_root *delayed_refs;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)
|
|
|
|
|
|| bytenr == 0 || num_bytes == 0)
|
|
|
|
|
if (!btrfs_qgroup_full_accounting(fs_info) || bytenr == 0 || num_bytes == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
record = kzalloc(sizeof(*record), GFP_NOFS);
|
|
|
|
|
if (!record)
|
|
|
|
@ -1970,7 +2001,7 @@ int btrfs_qgroup_trace_leaf_items(struct btrfs_trans_handle *trans,
|
|
|
|
|
u64 bytenr, num_bytes;
|
|
|
|
|
|
|
|
|
|
/* We can be called directly from walk_up_proc() */
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
|
|
|
if (!btrfs_qgroup_full_accounting(fs_info))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < nr; i++) {
|
|
|
|
@ -2346,7 +2377,7 @@ static int qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans,
|
|
|
|
|
int level;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
|
|
|
if (!btrfs_qgroup_full_accounting(fs_info))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* Wrong parameter order */
|
|
|
|
@ -2413,7 +2444,7 @@ int btrfs_qgroup_trace_subtree(struct btrfs_trans_handle *trans,
|
|
|
|
|
BUG_ON(root_level < 0 || root_level >= BTRFS_MAX_LEVEL);
|
|
|
|
|
BUG_ON(root_eb == NULL);
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
|
|
|
if (!btrfs_qgroup_full_accounting(fs_info))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
spin_lock(&fs_info->qgroup_lock);
|
|
|
|
@ -2747,7 +2778,7 @@ int btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, u64 bytenr,
|
|
|
|
|
* If quotas get disabled meanwhile, the resources need to be freed and
|
|
|
|
|
* we can't just exit here.
|
|
|
|
|
*/
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
|
|
|
|
|
if (!btrfs_qgroup_full_accounting(fs_info) ||
|
|
|
|
|
fs_info->qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING)
|
|
|
|
|
goto out_free;
|
|
|
|
|
|
|
|
|
@ -2816,6 +2847,9 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans)
|
|
|
|
|
u64 qgroup_to_skip;
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_SIMPLE)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
delayed_refs = &trans->transaction->delayed_refs;
|
|
|
|
|
qgroup_to_skip = delayed_refs->qgroup_to_skip;
|
|
|
|
|
while ((node = rb_first(&delayed_refs->dirty_extent_root))) {
|
|
|
|
@ -2931,7 +2965,7 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans)
|
|
|
|
|
qgroup_mark_inconsistent(fs_info);
|
|
|
|
|
spin_lock(&fs_info->qgroup_lock);
|
|
|
|
|
}
|
|
|
|
|
if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
|
|
|
if (btrfs_qgroup_enabled(fs_info))
|
|
|
|
|
fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_ON;
|
|
|
|
|
else
|
|
|
|
|
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_ON;
|
|
|
|
@ -2990,7 +3024,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
|
|
|
|
|
|
|
|
|
|
if (!committing)
|
|
|
|
|
mutex_lock(&fs_info->qgroup_ioctl_lock);
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
|
|
|
if (!btrfs_qgroup_enabled(fs_info))
|
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
quota_root = fs_info->quota_root;
|
|
|
|
@ -3076,7 +3110,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
|
|
|
|
|
qgroup_dirty(fs_info, dstgroup);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srcid) {
|
|
|
|
|
if (srcid && btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_FULL) {
|
|
|
|
|
srcgroup = find_qgroup_rb(fs_info, srcid);
|
|
|
|
|
if (!srcgroup)
|
|
|
|
|
goto unlock;
|
|
|
|
@ -3339,6 +3373,9 @@ static int qgroup_rescan_leaf(struct btrfs_trans_handle *trans,
|
|
|
|
|
int slot;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (!btrfs_qgroup_full_accounting(fs_info))
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
mutex_lock(&fs_info->qgroup_rescan_lock);
|
|
|
|
|
extent_root = btrfs_extent_root(fs_info,
|
|
|
|
|
fs_info->qgroup_rescan_progress.objectid);
|
|
|
|
@ -3419,10 +3456,15 @@ out:
|
|
|
|
|
|
|
|
|
|
static bool rescan_should_stop(struct btrfs_fs_info *fs_info)
|
|
|
|
|
{
|
|
|
|
|
return btrfs_fs_closing(fs_info) ||
|
|
|
|
|
test_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state) ||
|
|
|
|
|
!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
|
|
|
|
|
fs_info->qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN;
|
|
|
|
|
if (btrfs_fs_closing(fs_info))
|
|
|
|
|
return true;
|
|
|
|
|
if (test_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state))
|
|
|
|
|
return true;
|
|
|
|
|
if (!btrfs_qgroup_enabled(fs_info))
|
|
|
|
|
return true;
|
|
|
|
|
if (fs_info->qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN)
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
|
|
|
|
@ -3436,6 +3478,9 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
|
|
|
|
|
bool stopped = false;
|
|
|
|
|
bool did_leaf_rescans = false;
|
|
|
|
|
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_SIMPLE)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
path = btrfs_alloc_path();
|
|
|
|
|
if (!path)
|
|
|
|
|
goto out;
|
|
|
|
@ -3539,6 +3584,11 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_SIMPLE) {
|
|
|
|
|
btrfs_warn(fs_info, "qgroup rescan init failed, running in simple mode");
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!init_flags) {
|
|
|
|
|
/* we're resuming qgroup rescan at mount time */
|
|
|
|
|
if (!(fs_info->qgroup_flags &
|
|
|
|
@ -3569,7 +3619,7 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
|
|
|
|
|
btrfs_warn(fs_info,
|
|
|
|
|
"qgroup rescan init failed, qgroup is not enabled");
|
|
|
|
|
ret = -EINVAL;
|
|
|
|
|
} else if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) {
|
|
|
|
|
} else if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_DISABLED) {
|
|
|
|
|
/* Quota disable is in progress */
|
|
|
|
|
ret = -EBUSY;
|
|
|
|
|
}
|
|
|
|
@ -3828,7 +3878,7 @@ static int qgroup_reserve_data(struct btrfs_inode *inode,
|
|
|
|
|
u64 to_reserve;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &root->fs_info->flags) ||
|
|
|
|
|
if (btrfs_qgroup_mode(root->fs_info) == BTRFS_QGROUP_MODE_DISABLED ||
|
|
|
|
|
!is_fstree(root->root_key.objectid) || len == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
@ -3960,7 +4010,7 @@ static int __btrfs_qgroup_release_data(struct btrfs_inode *inode,
|
|
|
|
|
int trace_op = QGROUP_RELEASE;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &inode->root->fs_info->flags))
|
|
|
|
|
if (btrfs_qgroup_mode(inode->root->fs_info) == BTRFS_QGROUP_MODE_DISABLED)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* In release case, we shouldn't have @reserved */
|
|
|
|
@ -4071,7 +4121,7 @@ int btrfs_qgroup_reserve_meta(struct btrfs_root *root, int num_bytes,
|
|
|
|
|
struct btrfs_fs_info *fs_info = root->fs_info;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_DISABLED ||
|
|
|
|
|
!is_fstree(root->root_key.objectid) || num_bytes == 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
@ -4116,7 +4166,7 @@ void btrfs_qgroup_free_meta_all_pertrans(struct btrfs_root *root)
|
|
|
|
|
{
|
|
|
|
|
struct btrfs_fs_info *fs_info = root->fs_info;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_DISABLED ||
|
|
|
|
|
!is_fstree(root->root_key.objectid))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
@ -4132,7 +4182,7 @@ void __btrfs_qgroup_free_meta(struct btrfs_root *root, int num_bytes,
|
|
|
|
|
{
|
|
|
|
|
struct btrfs_fs_info *fs_info = root->fs_info;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_DISABLED ||
|
|
|
|
|
!is_fstree(root->root_key.objectid))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
@ -4191,7 +4241,7 @@ void btrfs_qgroup_convert_reserved_meta(struct btrfs_root *root, int num_bytes)
|
|
|
|
|
{
|
|
|
|
|
struct btrfs_fs_info *fs_info = root->fs_info;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) ||
|
|
|
|
|
if (btrfs_qgroup_mode(fs_info) == BTRFS_QGROUP_MODE_DISABLED ||
|
|
|
|
|
!is_fstree(root->root_key.objectid))
|
|
|
|
|
return;
|
|
|
|
|
/* Same as btrfs_qgroup_free_meta_prealloc() */
|
|
|
|
@ -4299,7 +4349,7 @@ int btrfs_qgroup_add_swapped_blocks(struct btrfs_trans_handle *trans,
|
|
|
|
|
int level = btrfs_header_level(subvol_parent) - 1;
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
|
|
|
if (!btrfs_qgroup_full_accounting(fs_info))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (btrfs_node_ptr_generation(subvol_parent, subvol_slot) >
|
|
|
|
@ -4409,7 +4459,7 @@ int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans,
|
|
|
|
|
int ret = 0;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
|
|
|
|
|
if (!btrfs_qgroup_full_accounting(fs_info))
|
|
|
|
|
return 0;
|
|
|
|
|
if (!is_fstree(root->root_key.objectid) || !root->reloc_root)
|
|
|
|
|
return 0;
|
|
|
|
|