reiserfs-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ivan Shapovalov <intelfx100@gmail.com>
To: reiserfs-devel@vger.kernel.org
Cc: Ivan Shapovalov <intelfx100@gmail.com>
Subject: [PATCH 6/6] reiser4: discard: allocate extent paddings.
Date: Sat, 13 Dec 2014 00:10:32 +0300	[thread overview]
Message-ID: <1418418632-18396-7-git-send-email-intelfx100@gmail.com> (raw)
In-Reply-To: <1418418632-18396-1-git-send-email-intelfx100@gmail.com>

Subsequent deallocation of newly allocated padding blocks is ensured by
writing the actual discarded extents back to the discard set.

Signed-off-by: Ivan Shapovalov <intelfx100@gmail.com>
---
 fs/reiser4/discard.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 44 insertions(+), 6 deletions(-)

diff --git a/fs/reiser4/discard.c b/fs/reiser4/discard.c
index 86ff6e4..68865d2 100644
--- a/fs/reiser4/discard.c
+++ b/fs/reiser4/discard.c
@@ -221,7 +221,15 @@ static inline struct list_head *get_next_at(struct list_head *pos,
 static inline int check_free_blocks(const reiser4_block_nr start,
 				    const reiser4_block_nr len)
 {
-	return reiser4_check_blocks(&start, &len, 0);
+	/*
+	 * NOTE: we do not use BA_PERMANENT in out allocations
+	 * even though these blocks are later deallocated with BA_DEFER
+	 * (via updating the delete set with newly allocated blocks).
+	 * The discard code is ran after the pre-commit hook so deallocated block
+	 * accounting is already done.
+	 */
+	return reiser4_alloc_blocks_exact (&start, &len, BLOCK_NOT_COUNTED,
+					   BA_FORMATTED) == 0;
 }
 
 /* Make sure that extents are sorted and merged */
@@ -255,6 +263,8 @@ static inline void check_blocknr_list_at(struct list_head *pos,
  * extent in the working space map. Try to "glue" the nearby
  * extents. Discard the (glued) extents with padded (or cut)
  * head and tail.
+ * The paddings, if any, are allocated before discarding, and the list
+ * is updated to contain all new allocations.
  *
  * Pre-conditions: @head points to the list of sorted and
  * merged extents.
@@ -274,6 +284,9 @@ static inline void check_blocknr_list_at(struct list_head *pos,
  * astart - actual start to discard (offset of the head padding);
  * alen - actual length to discard (length of glued aligned and padded extents).
  *
+ * estart - start of extent to be written back to the list
+ * eend - end (last block + 1) of extent to be written back to the list
+ *
  * Terminology in the comments:
  *
  * head - a part of extent at the beginning;
@@ -299,11 +312,14 @@ static int discard_sorted_merged_extents(struct list_head *head)
 		reiser4_block_nr len;
 		reiser4_block_nr end;
 		reiser4_block_nr astart; __s64 alen;
+		reiser4_block_nr estart, eend;
 
 		check_blocknr_list_at(pos, head);
 
 		start = blocknr_list_entry_start(pos);
 		len = blocknr_list_entry_len(pos);
+		estart = start;
+
 		/*
 		 * Step I. Cut or pad the head of extent
 		 *
@@ -326,6 +342,7 @@ static int discard_sorted_merged_extents(struct list_head *head)
 			 */
 			astart = start - headp;
 			alen = len + headp;
+			estart -= headp;
 		} else {
 			/*
 			 * head padding is dirty,
@@ -341,10 +358,11 @@ static int discard_sorted_merged_extents(struct list_head *head)
 		 *          Cut or pad the tail of the last extent.
 		 */
 		end = start + len;
+		eend = end;
 		tailp = extent_get_tailp(end, d_off, d_uni);
 
 		/*
-		 * This "gluing" loop updates @pos, @end, @tailp, @alen
+		 * This "gluing" loop updates @end, @tailp, @alen, @eend
 		 */
 		while (1) {
 			struct list_head *next;
@@ -366,10 +384,17 @@ static int discard_sorted_merged_extents(struct list_head *head)
 					/*
 					 * jump to the glued extent
 					 */
-					pos = next;
 					alen += (next_start + next_len - end);
 					end = next_start + next_len;
 					tailp = extent_get_tailp(end, d_off, d_uni);
+					eend = end;
+					/*
+					 * remove the glued extent from the list
+					 *
+					 * (don't update pos, current next->next
+					 * will become pos->next)
+					 */
+					blocknr_list_del(next);
 					/*
 					 * try to glue more extents
 					 */
@@ -395,13 +420,14 @@ static int discard_sorted_merged_extents(struct list_head *head)
 				 */
 				if (tailp == 0)
 					break;
-				else if (check_free_blocks(end, tailp))
+				else if (check_free_blocks(end, tailp)) {
 					/*
 					 * tail padding is clean,
 					 * pad the tail
 					 */
 					alen += tailp;
-				else
+					eend += tailp;
+				} else
 					/*
 					 * tail padding is dirty,
 					 * cut the tail
@@ -415,6 +441,18 @@ static int discard_sorted_merged_extents(struct list_head *head)
 		 * Step III. Discard the result
 		 */
 		if (alen > 0) {
+			assert("intelfx-74", estart < eend);
+			assert("intelfx-75", estart <= start);
+			assert("intelfx-76", estart <= astart);
+			assert("intelfx-77", start + len <= eend);
+			assert("intelfx-78", astart + alen <= eend);
+
+			/* here @eend becomes length */
+			eend -= estart;
+			assert("intelfx-79",
+			       reiser4_check_blocks(&estart, &eend, 1));
+			blocknr_list_update_extent(pos, &estart, &eend);
+
 			ret = __discard_extent(sb->s_bdev,
 					       astart * (sb->s_blocksize >> 9),
 					       alen * (sb->s_blocksize >> 9));
@@ -453,7 +491,7 @@ int discard_atom(txn_atom *atom, struct list_head *processed_set)
 	/* Sort the discard list, joining adjacent and overlapping extents. */
 	blocknr_list_sort_and_join(&discard_set);
 
-	/* Perform actual dirty work. */
+	/* Perform actual dirty work. The discard set may change at this point. */
 	ret = discard_sorted_merged_extents(&discard_set);
 
 	/* Add processed extents to the temporary list. */
-- 
2.1.3


  parent reply	other threads:[~2014-12-12 21:10 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-12 21:10 [PATCH 0/6] reiser4: discard support: "precise discard" aka padding of extents to erase unit boundaries Ivan Shapovalov
2014-12-12 21:10 ` [PATCH 1/6] reiser4: block_alloc: split block allocation accounting logic into separate functions for re-use Ivan Shapovalov
2014-12-12 21:10 ` [PATCH 2/6] reiser4: block_alloc, plugin/space/bitmap: add a method for "exact" block allocation Ivan Shapovalov
2014-12-19 15:43   ` Edward Shishkin
2014-12-12 21:10 ` [PATCH 3/6] reiser4: iterate over extents in discard_atom Ivan Shapovalov
2014-12-12 21:10 ` [PATCH 4/6] reiser4: discard: don't be overly smart when gluing extents in discard_sorted_merged_extents() Ivan Shapovalov
2014-12-19 20:24   ` Edward Shishkin
2014-12-12 21:10 ` [PATCH 5/6] reiser4: blocknrlist: add operations blocknr_list_del() and blocknr_list_update_extent() Ivan Shapovalov
2014-12-12 21:10 ` Ivan Shapovalov [this message]
2014-12-13 22:38 ` [PATCH 0/6] reiser4: discard support: "precise discard" aka padding of extents to erase unit boundaries Edward Shishkin
2014-12-14  8:03   ` Ivan Shapovalov
2014-12-15 19:30     ` Edward Shishkin
2014-12-19 15:46       ` Edward Shishkin

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=1418418632-18396-7-git-send-email-intelfx100@gmail.com \
    --to=intelfx100@gmail.com \
    --cc=reiserfs-devel@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).