[PATCH v4 1/3] Btrfs: split btrfs_qgroup_account_ref into four functions

2013-04-25 Thread Jan Schmidt
The function is separated into a preparation part and the three accounting
steps mentioned in the qgroups documentation. The goal is to make steps two
and three usable by the rescan functionality. A side effect is that the
function is restructured into readable subunits.

Signed-off-by: Jan Schmidt list.bt...@jan-o-sch.net
---
 fs/btrfs/qgroup.c |  253 +++--
 1 files changed, 148 insertions(+), 105 deletions(-)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index f175471..c50e5a5 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1185,6 +1185,144 @@ int btrfs_qgroup_record_ref(struct btrfs_trans_handle 
*trans,
return 0;
 }
 
+static int qgroup_account_ref_step1(struct btrfs_fs_info *fs_info,
+   struct ulist *roots, struct ulist *tmp,
+   u64 seq)
+{
+   struct ulist_node *unode;
+   struct ulist_iterator uiter;
+   struct ulist_node *tmp_unode;
+   struct ulist_iterator tmp_uiter;
+   struct btrfs_qgroup *qg;
+   int ret;
+
+   ULIST_ITER_INIT(uiter);
+   while ((unode = ulist_next(roots, uiter))) {
+   qg = find_qgroup_rb(fs_info, unode-val);
+   if (!qg)
+   continue;
+
+   ulist_reinit(tmp);
+   /* XXX id not needed */
+   ret = ulist_add(tmp, qg-qgroupid,
+   (u64)(uintptr_t)qg, GFP_ATOMIC);
+   if (ret  0)
+   return ret;
+   ULIST_ITER_INIT(tmp_uiter);
+   while ((tmp_unode = ulist_next(tmp, tmp_uiter))) {
+   struct btrfs_qgroup_list *glist;
+
+   qg = (struct btrfs_qgroup *)(uintptr_t)tmp_unode-aux;
+   if (qg-refcnt  seq)
+   qg-refcnt = seq + 1;
+   else
+   ++qg-refcnt;
+
+   list_for_each_entry(glist, qg-groups, next_group) {
+   ret = ulist_add(tmp, glist-group-qgroupid,
+   (u64)(uintptr_t)glist-group,
+   GFP_ATOMIC);
+   if (ret  0)
+   return ret;
+   }
+   }
+   }
+
+   return 0;
+}
+
+static int qgroup_account_ref_step2(struct btrfs_fs_info *fs_info,
+   struct ulist *roots, struct ulist *tmp,
+   u64 seq, int sgn, u64 num_bytes,
+   struct btrfs_qgroup *qgroup)
+{
+   struct ulist_node *unode;
+   struct ulist_iterator uiter;
+   struct btrfs_qgroup *qg;
+   struct btrfs_qgroup_list *glist;
+   int ret;
+
+   ulist_reinit(tmp);
+   ret = ulist_add(tmp, qgroup-qgroupid, (uintptr_t)qgroup, GFP_ATOMIC);
+   if (ret  0)
+   return ret;
+
+   ULIST_ITER_INIT(uiter);
+   while ((unode = ulist_next(tmp, uiter))) {
+   qg = (struct btrfs_qgroup *)(uintptr_t)unode-aux;
+   if (qg-refcnt  seq) {
+   /* not visited by step 1 */
+   qg-rfer += sgn * num_bytes;
+   qg-rfer_cmpr += sgn * num_bytes;
+   if (roots-nnodes == 0) {
+   qg-excl += sgn * num_bytes;
+   qg-excl_cmpr += sgn * num_bytes;
+   }
+   qgroup_dirty(fs_info, qg);
+   }
+   WARN_ON(qg-tag = seq);
+   qg-tag = seq;
+
+   list_for_each_entry(glist, qg-groups, next_group) {
+   ret = ulist_add(tmp, glist-group-qgroupid,
+   (uintptr_t)glist-group, GFP_ATOMIC);
+   if (ret  0)
+   return ret;
+   }
+   }
+
+   return 0;
+}
+
+static int qgroup_account_ref_step3(struct btrfs_fs_info *fs_info,
+   struct ulist *roots, struct ulist *tmp,
+   u64 seq, int sgn, u64 num_bytes)
+{
+   struct ulist_node *unode;
+   struct ulist_iterator uiter;
+   struct btrfs_qgroup *qg;
+   struct ulist_node *tmp_unode;
+   struct ulist_iterator tmp_uiter;
+   int ret;
+
+   ULIST_ITER_INIT(uiter);
+   while ((unode = ulist_next(roots, uiter))) {
+   qg = find_qgroup_rb(fs_info, unode-val);
+   if (!qg)
+   continue;
+
+   ulist_reinit(tmp);
+   ret = ulist_add(tmp, qg-qgroupid, (uintptr_t)qg, GFP_ATOMIC);
+   if (ret  0)
+   return ret;
+
+   ULIST_ITER_INIT(tmp_uiter);
+   while ((tmp_unode = 

Re: [PATCH v4 1/3] Btrfs: split btrfs_qgroup_account_ref into four functions

2013-04-25 Thread Wang Shilong
Hello Jan,

 The function is separated into a preparation part and the three accounting
 steps mentioned in the qgroups documentation. The goal is to make steps two
 and three usable by the rescan functionality. A side effect is that the
 function is restructured into readable subunits.
 

In fact, you only reuse step1 function, not step2,step3 function..
Otherwise, looks good to me.

Reviewed-by:  Wang Shilong wangsl-f...@cn.fujitsu.com

--
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