linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: amir73il@users.sourceforge.net
To: linux-ext4@vger.kernel.org
Cc: tytso@mit.edu, Amir Goldstein <amir73il@users.sf.net>,
	Yongqiang Yang <xiaoqiangnk@gmail.com>
Subject: [PATCH RFC 29/30] ext4: snapshot cleanup - shrink deleted snapshots
Date: Mon,  9 May 2011 19:41:47 +0300	[thread overview]
Message-ID: <1304959308-11122-30-git-send-email-amir73il@users.sourceforge.net> (raw)
In-Reply-To: <1304959308-11122-1-git-send-email-amir73il@users.sourceforge.net>

From: Amir Goldstein <amir73il@users.sf.net>

Free blocks of deleted snapshots, which are not in use by an older
non-deleted snapshot.  Shrinking helps reclaiming disk space
while older snapshots are currently in use (enabled).
We modify the indirect inode truncate helper functions so that they
can be used by the snapshot cleanup functions to free blocks
selectively according to a COW bitmap buffer.

Signed-off-by: Amir Goldstein <amir73il@users.sf.net>
Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
---
 fs/ext4/ext4.h  |   10 ++++++++++
 fs/ext4/inode.c |   51 +++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 7650515..07629ce 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1905,6 +1905,16 @@ extern void ext4_free_branches(handle_t *handle, struct inode *inode,
 				struct buffer_head *parent_bh,
 				__le32 *first, __le32 *last,
 				int depth);
+extern void ext4_free_data_cow(handle_t *handle, struct inode *inode,
+			   struct buffer_head *this_bh,
+			   __le32 *first, __le32 *last,
+			   const char *bitmap, int bit,
+			   int *pfreed_blocks);
+
+#define ext4_free_data(handle, inode, bh, first, last)		\
+	ext4_free_data_cow(handle, inode, bh, first, last,	\
+			    NULL, 0, NULL)
+
 /* ioctl.c */
 extern long ext4_ioctl(struct file *, unsigned int, unsigned long);
 extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index d46da6a..e3bfee2 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4546,11 +4546,15 @@ no_top:
  * Return 0 on success, 1 on invalid block range
  * and < 0 on fatal error.
  */
-static int ext4_clear_blocks(handle_t *handle, struct inode *inode,
-			     struct buffer_head *bh,
-			     ext4_fsblk_t block_to_free,
-			     unsigned long count, __le32 *first,
-			     __le32 *last)
+/*
+ * ext4_clear_blocks_cow - Zero a number of block pointers (consult COW bitmap)
+ * @bitmap:	COW bitmap to consult when shrinking deleted snapshot
+ * @bit:	bit number representing the @first block
+ */
+static int ext4_clear_blocks_cow(handle_t *handle, struct inode *inode,
+		struct buffer_head *bh, ext4_fsblk_t block_to_free,
+		unsigned long count, __le32 *first, __le32 *last,
+		const char *bitmap, int bit)
 {
 	__le32 *p;
 	int	flags = EXT4_FREE_BLOCKS_FORGET | EXT4_FREE_BLOCKS_VALIDATED;
@@ -4590,8 +4594,12 @@ static int ext4_clear_blocks(handle_t *handle, struct inode *inode,
 		}
 	}
 
-	for (p = first; p < last; p++)
+	for (p = first; p < last; p++) {
+		if (*p && bitmap && ext4_test_bit(bit + (p - first), bitmap))
+			/* don't free block used by older snapshot */
+			continue;
 		*p = 0;
+	}
 
 	ext4_free_blocks(handle, inode, NULL, block_to_free, count, flags);
 	return 0;
@@ -4619,9 +4627,17 @@ out_err:
  * @this_bh will be %NULL if @first and @last point into the inode's direct
  * block pointers.
  */
-static void ext4_free_data(handle_t *handle, struct inode *inode,
+/*
+ * ext4_free_data_cow - free a list of data blocks (consult COW bitmap)
+ * @bitmap:	   COW bitmap to consult when shrinking deleted snapshot
+ * @bit:	   bit number representing the @first block
+ * @pfreed_blocks: return number of freed blocks
+ */
+void ext4_free_data_cow(handle_t *handle, struct inode *inode,
 			   struct buffer_head *this_bh,
-			   __le32 *first, __le32 *last)
+			   __le32 *first, __le32 *last,
+			   const char *bitmap, int bit,
+			   int *pfreed_blocks)
 {
 	ext4_fsblk_t block_to_free = 0;    /* Starting block # of a run */
 	unsigned long count = 0;	    /* Number of blocks in the run */
@@ -4645,6 +4661,11 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
 
 	for (p = first; p < last; p++) {
 		nr = le32_to_cpu(*p);
+		if (nr && bitmap && ext4_test_bit(bit + (p - first), bitmap))
+			/* don't free block used by older snapshot */
+			nr = 0;
+		if (nr && pfreed_blocks)
+			++(*pfreed_blocks);
 		if (nr) {
 			/* accumulate blocks to free if they're contiguous */
 			if (count == 0) {
@@ -4654,9 +4675,10 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
 			} else if (nr == block_to_free + count) {
 				count++;
 			} else {
-				err = ext4_clear_blocks(handle, inode, this_bh,
-						        block_to_free, count,
-						        block_to_free_p, p);
+				err = ext4_clear_blocks_cow(handle, inode,
+					       this_bh, block_to_free, count,
+					       block_to_free_p, p, bitmap,
+					       bit + (block_to_free_p - first));
 				if (err)
 					break;
 				block_to_free = nr;
@@ -4666,9 +4688,10 @@ static void ext4_free_data(handle_t *handle, struct inode *inode,
 		}
 	}
 
-	if (!err && count > 0)
-		err = ext4_clear_blocks(handle, inode, this_bh, block_to_free,
-					count, block_to_free_p, p);
+	if (count > 0)
+		err = ext4_clear_blocks_cow(handle, inode, this_bh,
+				block_to_free, count, block_to_free_p, p,
+				bitmap, bit + (block_to_free_p - first));
 	if (err < 0)
 		/* fatal error */
 		return;
-- 
1.7.0.4


  parent reply	other threads:[~2011-05-09 16:44 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-05-09 16:41 [PATCH RFC 00/30] Ext4 snapshots - core patches amir73il
2011-05-09 16:41 ` [PATCH RFC 01/30] ext4: EXT4 snapshots (Experimental) amir73il
2011-06-06 14:50   ` Lukas Czerner
2011-06-07  9:28     ` Amir G.
2011-06-07 10:42       ` Lukas Czerner
2011-06-07 13:20         ` Amir G.
2011-05-09 16:41 ` [PATCH RFC 02/30] ext4: snapshot debugging support amir73il
2011-06-06 15:08   ` Lukas Czerner
2011-06-07  9:59     ` Amir G.
2011-06-07 10:49       ` Lukas Czerner
2011-05-09 16:41 ` [PATCH RFC 03/30] ext4: snapshot hooks - inside JBD hooks amir73il
2011-06-06 15:53   ` Lukas Czerner
2011-06-06 16:08     ` Amir G.
2011-06-06 19:01     ` Amir G.
2011-05-09 16:41 ` [PATCH RFC 04/30] ext4: snapshot hooks - block bitmap access amir73il
2011-05-09 16:41 ` [PATCH RFC 05/30] ext4: snapshot hooks - delete blocks amir73il
2011-06-07 11:24   ` Lukas Czerner
2011-06-07 13:24     ` Amir G.
2011-06-07 13:32       ` Lukas Czerner
2011-05-09 16:41 ` [PATCH RFC 06/30] ext4: snapshot hooks - move data blocks amir73il
2011-05-09 16:41 ` [PATCH RFC 07/30] ext4: snapshot hooks - direct I/O amir73il
2011-05-09 16:41 ` [PATCH RFC 08/30] ext4: snapshot hooks - move extent file data blocks amir73il
2011-05-09 16:41 ` [PATCH RFC 09/30] ext4: snapshot file amir73il
2011-06-02 11:52   ` Amir G.
2011-05-09 16:41 ` [PATCH RFC 10/30] ext4: snapshot file - read through to block device amir73il
2011-05-09 16:41 ` [PATCH RFC 11/30] ext4: snapshot file - permissions amir73il
2011-05-09 16:41 ` [PATCH RFC 12/30] ext4: snapshot file - store on disk amir73il
2011-05-09 16:41 ` [PATCH RFC 13/30] ext4: snapshot file - increase maximum file size limit to 16TB amir73il
2011-06-02 11:47   ` Amir G.
2011-06-03  0:48     ` Ted Ts'o
2011-06-03  4:45       ` Amir G.
2011-05-09 16:41 ` [PATCH RFC 14/30] ext4: snapshot block operations amir73il
2011-05-09 16:41 ` [PATCH RFC 15/30] ext4: snapshot block operation - copy blocks to snapshot amir73il
2011-05-09 16:41 ` [PATCH RFC 16/30] ext4: snapshot block operation - move " amir73il
2011-05-09 16:41 ` [PATCH RFC 17/30] ext4: snapshot control amir73il
2011-05-09 16:41 ` [PATCH RFC 18/30] ext4: snapshot control - fix new snapshot amir73il
2011-05-09 16:41 ` [PATCH RFC 19/30] ext4: snapshot control - reserve disk space for snapshot amir73il
2011-05-09 16:41 ` [PATCH RFC 20/30] ext4: snapshot journaled - increase transaction credits amir73il
2011-05-09 16:41 ` [PATCH RFC 21/30] ext4: snapshot journaled - implement journal_release_buffer() amir73il
2011-05-09 16:41 ` [PATCH RFC 22/30] ext4: snapshot journaled - bypass to save credits amir73il
2011-05-09 16:41 ` [PATCH RFC 23/30] ext4: snapshot journaled - trace COW/buffer credits amir73il
2011-05-09 16:41 ` [PATCH RFC 24/30] ext4: snapshot list support amir73il
2011-05-09 16:41 ` [PATCH RFC 25/30] ext4: snapshot race conditions - concurrent COW operations amir73il
2011-05-09 16:41 ` [PATCH RFC 26/30] ext4: snapshot race conditions - tracked reads amir73il
2011-05-09 16:41 ` [PATCH RFC 27/30] ext4: snapshot exclude - the exclude bitmap amir73il
2011-05-09 16:41 ` [PATCH RFC 28/30] ext4: snapshot cleanup amir73il
2011-05-09 16:41 ` amir73il [this message]
2011-05-09 16:41 ` [PATCH RFC 30/30] ext4: snapshot rocompat - enable rw mount amir73il
2011-06-06 13:08 ` [PATCH RFC 00/30] Ext4 snapshots - core patches Lukas Czerner
2011-06-06 14:32   ` Amir G.
2011-06-06 15:31     ` Eric Sandeen
2011-06-06 16:05       ` Lukas Czerner
2011-06-06 20:40         ` Ted Ts'o
2011-06-07 13:59           ` Ric Wheeler
2011-06-07 15:37             ` Ted Ts'o
2011-06-06 16:33       ` Andreas Dilger
2011-06-06 16:42         ` Eric Sandeen
2011-06-06 19:58           ` Lukáš Czerner
2011-06-06 18:25         ` Amir G.
2011-06-06 20:55       ` Ted Ts'o
2011-06-07  5:17         ` Andreas Dilger
2011-06-07  5:58           ` Amir G.
2011-06-07 10:09             ` Lukas Czerner
2011-06-07 13:01               ` Amir G.
2011-06-07 13:50                 ` Ric Wheeler
2011-06-07 14:39                   ` Amir G.
2011-06-07  6:40         ` Amir G.
2011-06-07 15:26 ` Josef Bacik
2011-06-07 16:46   ` Amir G.
2011-06-07 16:54     ` Josef Bacik
2011-06-07 18:22       ` Amir G.
2011-06-07 17:14     ` Sunil Mushran
2011-06-07 17:30       ` Ted Ts'o
2011-06-07 17:54       ` Amir G.

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=1304959308-11122-30-git-send-email-amir73il@users.sourceforge.net \
    --to=amir73il@users.sourceforge.net \
    --cc=amir73il@users.sf.net \
    --cc=linux-ext4@vger.kernel.org \
    --cc=tytso@mit.edu \
    --cc=xiaoqiangnk@gmail.com \
    /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).