Hello Jan, > btrfs_dec_ref() queued a delayed ref for owner of a tree block. The qgroup > tracking is based on delayed refs. The owner of a tree block is set when a > tree block is allocated, it is never updated. > > When you allocate a tree block and then remove the subvolume that did the > allocation, the qgroup accounting for that removal is correct. However, the > removal was accounted again for each subvolume deletion that also referenced > the tree block, because accounting was erroneously based on the owner. > > Instead of queueing delayed refs for the non-existent owner, we now > queue delayed refs for the root being removed. This fixes the qgroup > accounting.
Thanks for tracking this, i apply your patch, and using the flowing patch, found the problem still exist, the test script like the following: #!/bin/sh for i in $(seq 1000) do dd if=/dev/zero of=<mnt>/$i""aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bs=10K count=1 done btrfs sub snapshot <mnt> <mnt>/1 for i in $(seq 100) do btrfs sub snapshot <mnt>/$i <mnt>/$(($i+1)) done for i in $(seq 101) do btrfs sub delete <mnt>/$i done Thanks, Wang > > Signed-off-by: Jan Schmidt <list.bt...@jan-o-sch.net> > Tested-by: <dustym...@gmail.com> > --- > fs/btrfs/extent-tree.c | 14 +++++++++----- > 1 files changed, 9 insertions(+), 5 deletions(-) > > diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c > index d58bef1..7846cae 100644 > --- a/fs/btrfs/extent-tree.c > +++ b/fs/btrfs/extent-tree.c > @@ -3004,12 +3004,11 @@ out: > static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, > struct btrfs_root *root, > struct extent_buffer *buf, > - int full_backref, int inc, int for_cow) > + int full_backref, u64 ref_root, int inc, int for_cow) > { > u64 bytenr; > u64 num_bytes; > u64 parent; > - u64 ref_root; > u32 nritems; > struct btrfs_key key; > struct btrfs_file_extent_item *fi; > @@ -3019,7 +3018,6 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle > *trans, > int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, > u64, u64, u64, u64, u64, u64, int); > > - ref_root = btrfs_header_owner(buf); > nritems = btrfs_header_nritems(buf); > level = btrfs_header_level(buf); > > @@ -3075,13 +3073,19 @@ fail: > int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, > struct extent_buffer *buf, int full_backref, int for_cow) > { > - return __btrfs_mod_ref(trans, root, buf, full_backref, 1, for_cow); > + u64 ref_root; > + > + ref_root = btrfs_header_owner(buf); > + > + return __btrfs_mod_ref(trans, root, buf, full_backref, ref_root, > + 1, for_cow); > } > > int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, > struct extent_buffer *buf, int full_backref, int for_cow) > { > - return __btrfs_mod_ref(trans, root, buf, full_backref, 0, for_cow); > + return __btrfs_mod_ref(trans, root, buf, full_backref, root->objectid, > + 0, for_cow); > } > > static int write_one_cache_group(struct btrfs_trans_handle *trans, > -- > 1.7.2.2 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html