All of lore.kernel.org
 help / color / mirror / Atom feed
From: Qu Wenruo <quwenruo@cn.fujitsu.com>
To: <linux-btrfs@vger.kernel.org>
Subject: [PATCH 07/18] btrfs: qgroup: Add function qgroup_update_counters().
Date: Tue, 21 Apr 2015 14:21:23 +0800	[thread overview]
Message-ID: <1429597294-11875-8-git-send-email-quwenruo@cn.fujitsu.com> (raw)
In-Reply-To: <1429597294-11875-1-git-send-email-quwenruo@cn.fujitsu.com>

Add function qgroup_update_counters(), which will update related
qgroups' rfer/excl according to old/new_roots.

This is one of the two core functions for the new qgroup implement.

This is based on btrfs_adjust_coutners() but with clearer logic and
comment.

Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
 fs/btrfs/qgroup.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 120 insertions(+)

diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
index 17a974c..a780f8f 100644
--- a/fs/btrfs/qgroup.c
+++ b/fs/btrfs/qgroup.c
@@ -1761,6 +1761,126 @@ static int qgroup_update_refcnt(struct btrfs_fs_info *fs_info,
 }
 
 /*
+ * Update qgroup rfer/excl counters.
+ * Rfer update is easy, codes can explain themselves.
+ * Excl update is tricky, the update is split into 2 part.
+ * Part 1: Possible exclusive <-> sharing detect:
+ *	|	A	|	!A	|
+ *  -------------------------------------
+ *  B	|	*	|	-	|
+ *  -------------------------------------
+ *  !B	|	+	|	**	|
+ *  -------------------------------------
+ *
+ * Conditions:
+ * A:	cur_old_roots < nr_old_roots	(not exclusive before)
+ * !A:	cur_old_roots == nr_old_roots	(possible exclusive before)
+ * B:	cur_new_roots < nr_new_roots	(not exclusive now)
+ * !B:	cur_new_roots == nr_new_roots	(possible exclsuive now)
+ *
+ * Results:
+ * +: Possible sharing -> exclusive	-: Possible exclusive -> sharing
+ * *: Definitely not changed.		**: Possible unchanged.
+ *
+ * For !A and !B condition, the exception is cur_old/new_roots == 0 case.
+ *
+ * To make the logic clear, we first use condition A and B to split
+ * combination into 4 results.
+ *
+ * Then, for result "+" and "-", check old/new_roots == 0 case, as in them
+ * only on variant maybe 0.
+ *
+ * Lastly, check result **, since there are 2 variants maybe 0, split them
+ * again(2x2).
+ * But this time we don't need to consider other things, the codes and logic
+ * is easy to understand now.
+ */
+static int qgroup_update_counters(struct btrfs_fs_info *fs_info,
+				  struct ulist *qgroups,
+				  u64 nr_old_roots,
+				  u64 nr_new_roots,
+				  u64 num_bytes, u64 seq)
+{
+	struct ulist_node *unode;
+	struct ulist_iterator uiter;
+	struct btrfs_qgroup *qg;
+	u64 cur_new_count, cur_old_count;
+
+	ULIST_ITER_INIT(&uiter);
+	while ((unode = ulist_next(qgroups, &uiter))) {
+		bool dirty = false;
+
+		qg = u64_to_ptr(unode->aux);
+		cur_old_count = btrfs_qgroup_get_old_refcnt(qg, seq);
+		cur_new_count = btrfs_qgroup_get_new_refcnt(qg, seq);
+
+		/* Rfer update part */
+		if (cur_old_count == 0 && cur_new_count > 0) {
+			qg->rfer += num_bytes;
+			qg->rfer_cmpr += num_bytes;
+			dirty = true;
+		}
+		if (cur_old_count > 0 && cur_new_count == 0) {
+			qg->rfer -= num_bytes;
+			qg->rfer_cmpr -= num_bytes;
+			dirty = true;
+		}
+
+		/* Excl update part */
+		/* Exclusive/none -> shared case */
+		if (cur_old_count == nr_old_roots &&
+		    cur_new_count < nr_new_roots) {
+			/* Exclusive -> shared */
+			if (cur_old_count != 0) {
+				qg->excl -= num_bytes;
+				qg->excl_cmpr -= num_bytes;
+				dirty = true;
+			}
+		}
+
+		/* Shared -> exclusive/none case */
+		if (cur_old_count < nr_old_roots &&
+		    cur_new_count == nr_new_roots) {
+			/* Shared->exclusive */
+			if (cur_new_count != 0) {
+				qg->excl += num_bytes;
+				qg->excl_cmpr += num_bytes;
+				dirty = true;
+			}
+		}
+
+		/* Exclusive/none -> exclusive/none case */
+		if (cur_old_count == nr_old_roots &&
+		    cur_new_count == nr_new_roots) {
+			if (cur_old_count == 0) {
+				/* None -> exclusive/none */
+
+				if (cur_new_count != 0) {
+					/* None -> exclusive */
+					qg->excl += num_bytes;
+					qg->excl_cmpr += num_bytes;
+					dirty = true;
+				}
+				/* None -> none, nothing changed */
+			} else {
+				/* Exclusive -> exclusive/none */
+
+				if (cur_new_count == 0) {
+					/* Exclusive -> none */
+					qg->excl -= num_bytes;
+					qg->excl_cmpr -= num_bytes;
+					dirty = true;
+				}
+				/* Exclusive -> exclusive, nothing changed */
+			}
+		}
+		if (dirty)
+			qgroup_dirty(fs_info, qg);
+	}
+	return 0;
+}
+
+/*
  * This adjusts the counters for all referenced qgroups if need be.
  */
 static int qgroup_adjust_counters(struct btrfs_fs_info *fs_info,
-- 
2.3.5


  parent reply	other threads:[~2015-04-21  6:21 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-21  6:21 [PATCH 00/18] New extent-oriented qgroup mechanism with minor cleanup Qu Wenruo
2015-04-21  6:21 ` [PATCH 01/18] btrfs: backref: Don't merge refs which are not for same block Qu Wenruo
2015-04-21  6:21 ` [PATCH 02/18] btrfs: delayed-ref: Use list to replace the ref_root in ref_head Qu Wenruo
2015-04-21  6:21 ` [PATCH 03/18] btrfs: delayed-ref: Cleanup the unneeded functions Qu Wenruo
2015-04-21  6:21 ` [PATCH 04/18] btrfs: qgroup: Cleanup open-coded old/new_refcnt update and read Qu Wenruo
2015-04-21  6:21 ` [PATCH 05/18] btrfs: extent-tree: Use ref_node to replace unneeded parameters in __inc_extent_ref() and __free_extent() Qu Wenruo
2015-04-21  6:21 ` [PATCH 06/18] btrfs: qgroup: Add function qgroup_update_refcnt() Qu Wenruo
2015-04-21  6:21 ` Qu Wenruo [this message]
2015-04-21  6:21 ` [PATCH 08/18] btrfs: qgroup: Record possible quota-related extent for qgroup Qu Wenruo
2015-04-21  6:21 ` [PATCH 09/18] btrfs: qgroup: Add new function to record old_roots Qu Wenruo
2015-04-21  6:21 ` [PATCH 10/18] btrfs: backref: Add special time_seq == (u64)-1 case for btrfs_find_all_roots() Qu Wenruo
2015-04-21  6:21 ` [PATCH 11/18] btrfs: qgroup: Add new qgroup calculation function btrfs_qgroup_account_extents() Qu Wenruo
2015-04-21  6:21 ` [PATCH 12/18] btrfs: qgroup: Switch rescan to new mechanism Qu Wenruo
2015-04-21  6:21 ` [PATCH 13/18] btrfs: qgroup: Switch to new extent-oriented qgroup mechanism Qu Wenruo
2015-04-21  6:21 ` [PATCH 14/18] btrfs: qgroup: Switch self test to " Qu Wenruo
2015-04-21  6:21 ` [PATCH 15/18] btrfs: qgroup: Cleanup the old ref_node-oriented mechanism Qu Wenruo
2015-04-21  6:21 ` [PATCH 16/18] btrfs: ulist: Add ulist_del() function Qu Wenruo
2015-04-21  6:21 ` [PATCH 17/18] btrfs: qgroup: Add the ability to skip given qgroup for old/new_roots Qu Wenruo
2015-04-21  6:21 ` [PATCH 18/18] btrfs: qgroup: Make snapshot accounting work with new extent-oriented qgroup Qu Wenruo
     [not found] ` <CAP9B-QkT5dY7GkMgiumq6HCszB0aSjcjYidcYFFzSvCFcCEU3A@mail.gmail.com>
2015-04-29  1:55   ` [PATCH 00/18] New extent-oriented qgroup mechanism with minor cleanup Qu Wenruo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1429597294-11875-8-git-send-email-quwenruo@cn.fujitsu.com \
    --to=quwenruo@cn.fujitsu.com \
    --cc=linux-btrfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.