Running generic/019 with qgroups on the scratch device enabled is
almost guaranteed to trigger the BUG_ON in btrfs_free_tree_block. It's
supposed to trigger only on -ENOMEM, in reality, however, it's possible
to get -EIO from btrfs_qgroup_trace_extent_post. This function just
finds the roots of the extent being tracked and sets the qrecord->old_roots
list. If this operation fails nothing critical happens except the
quota accounting can be considered wrong. In such case just set the
INCONSISTENT flag for the quota and be done with it.
Signed-off-by: Nikolay Borisov <nborisov@xxxxxxxx>
---
Qu,
This fixes the crash for me, however I'm not entirely sure it's really the
best fix since it's leaking the usage of INCONSISTENT out of qgroup.c. Ideally
I'd like to avoid this. Since you have more experience with qgroups and also you
introduced the extent tracking code in add_delayed_tree_ref how does
look to you?
fs/btrfs/delayed-ref.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index a1a40cf382e3..1e9aa18cc0d8 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -820,8 +820,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
num_bytes, parent, ref_root, level, action);
spin_unlock(&delayed_refs->lock);
- if (qrecord_inserted)
- return btrfs_qgroup_trace_extent_post(fs_info, record);
+ if (qrecord_inserted) {
+ int ret = btrfs_qgroup_trace_extent_post(fs_info, record);
+ if (ret != -ENOMEM)
+ fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
+ else
+ return -ENOMEM;
+ }
return 0;
free_head_ref:
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html