All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/15] ext4: add new online resize interface
@ 2011-11-19  9:57 Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 01/15] ext4: add a function which extends a group without checking parameters Yongqiang Yang
                   ` (15 more replies)
  0 siblings, 16 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4

Hi all,

This patch series adds new resize implementation to ext4.

-- What's new resize implementation?
   It is a new online resize interface for ext4.  It can be used via
   ioctl with EXT4_IOC_RESIZE_FS and a 64 bit integer indicating size
   of the resized fs in block.

-- Difference between current resize and new resize.
   New resize lets kernel do all work, like allocating bitmaps and
   inode tables and can support flex_bg and BLOCK_UNINIT features.
   Besides these, new resize is much faster than current resize.

   Below are benchmarks I made on my personal computer, fses with
   flex_bg size = 16 were resized to 230GB evry time. The first
   row shows the size of a fs from which the fs was resized to 230GB.
   The datas were collected by 'time resize2fs'.

                      new resize
                20GB          50GB      100GB
      real    0m3.558s     0m2.891s    0m0.394s
      user    0m0.004s     0m0.000s    0m0.394s
      sys     0m0.048s     0m0.048s    0m0.028s

                      current resize
                20GB          50GB      100GB
      real    5m2.770s     4m43.757s  3m14.840s
      user    0m0.040s     0m0.032s   0m0.024s
      sys     0m0.464s     0m0.432s   0m0.324s

   According to data above, new resize is faster than current resize in both
   user and sys time.  New resize performs well in sys time, because it
   supports BLOCK_UNINIT and adds multi-groups each time.

-- About supporting new features.
   YES! New resize can support new feature like bigalloc and exclude bitmap
   easily.  Because it lets kernel do all work.

 V3->V4:
   rename __ext4_group_extend to ext4_group_extend_no_check.

 V2->V3:
   initialize block bitmap of last group.
   remove code initalizing inode bitmap and inode tables.

Yongqiang.

git diff --stat

 Documentation/filesystems/ext4.txt |    7 +
 fs/ext4/ext4.h                     |   10 +
 fs/ext4/ioctl.c                    |   39 ++
 fs/ext4/resize.c                   | 1167 +++++++++++++++++++++++++++---------
 4 files changed, 942 insertions(+), 281 deletions(-)



^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v4 01/15] ext4: add a function which extends a group without checking parameters
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 02/15] ext4: add a function which adds a new desc to a fs Yongqiang Yang
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch added a function named ext4_group_extend_no_check() whose code
is copied from ext4_group_extend().  ext4_group_extend_no_check() assumes
the parameter is valid and has been checked by caller.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/resize.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 996780a..ac5565c 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -969,6 +969,59 @@ exit_put:
 } /* ext4_group_add */
 
 /*
+ * extend a group without checking assuming that checking has been done.
+ */
+static int ext4_group_extend_no_check(struct super_block *sb,
+			ext4_fsblk_t o_blocks_count, ext4_grpblk_t add)
+{
+	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+	handle_t *handle;
+	int err = 0, err2;
+
+	/* We will update the superblock, one block bitmap, and
+	 * one group descriptor via ext4_group_add_blocks().
+	 */
+	handle = ext4_journal_start_sb(sb, 3);
+	if (IS_ERR(handle)) {
+		err = PTR_ERR(handle);
+		ext4_warning(sb, "error %d on journal start", err);
+		goto out;
+	}
+
+	err = ext4_journal_get_write_access(handle, EXT4_SB(sb)->s_sbh);
+	if (err) {
+		ext4_warning(sb, "error %d on journal write access", err);
+		ext4_journal_stop(handle);
+		goto out;
+	}
+
+	ext4_blocks_count_set(es, o_blocks_count + add);
+	ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count,
+		   o_blocks_count + add);
+	/* We add the blocks to the bitmap and set the group need init bit */
+	err = ext4_group_add_blocks(handle, sb, o_blocks_count, add);
+	if (err)
+		goto exit_journal;
+	ext4_handle_dirty_super(handle, sb);
+	ext4_debug("freed blocks %llu through %llu\n", o_blocks_count,
+		   o_blocks_count + add);
+exit_journal:
+	err2 = ext4_journal_stop(handle);
+	if (err2 && !err)
+		err = err2;
+
+	if (!err) {
+		if (test_opt(sb, DEBUG))
+			printk(KERN_DEBUG "EXT4-fs: extended group to %llu "
+			       "blocks\n", ext4_blocks_count(es));
+		update_backups(sb, EXT4_SB(sb)->s_sbh->b_blocknr, (char *)es,
+			       sizeof(struct ext4_super_block));
+	}
+out:
+	return err;
+}
+
+/*
  * Extend the filesystem to the new number of blocks specified.  This entry
  * point is only used to extend the current filesystem to the end of the last
  * existing group.  It can be accessed via ioctl, or by "remount,resize=<size>"
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 02/15] ext4: add a function which adds a new desc to a fs
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 01/15] ext4: add a function which extends a group without checking parameters Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 03/15] ext4: add a function which sets up a new group desc Yongqiang Yang
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch adds a function named ext4_add_new_desc() which adds
a new desc to a fs and whose code is copied from ext4_group_add().

The function will be used by new resize implementation.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/resize.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index ac5565c..9a5486e 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -735,6 +735,48 @@ exit_err:
 	}
 }
 
+/*
+ * ext4_add_new_desc() adds group descriptor of group @group
+ *
+ * @handle: journal handle
+ * @sb; super block
+ * @group: the group no. of the first group desc to be added
+ * @resize_inode: the resize inode
+ */
+static int ext4_add_new_desc(handle_t *handle, struct super_block *sb,
+			     ext4_group_t group, struct inode *resize_inode)
+{
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct ext4_super_block *es = sbi->s_es;
+	struct buffer_head *gdb_bh;
+	int gdb_off, gdb_num, err = 0;
+	int reserved_gdb = ext4_bg_has_super(sb, group) ?
+		le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
+
+	gdb_off = group % EXT4_DESC_PER_BLOCK(sb);
+	gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
+
+	/*
+	 * We will only either add reserved group blocks to a backup group
+	 * or remove reserved blocks for the first group in a new group block.
+	 * Doing both would be mean more complex code, and sane people don't
+	 * use non-sparse filesystems anymore.  This is already checked above.
+	 */
+	if (gdb_off) {
+		gdb_bh = sbi->s_group_desc[gdb_num];
+		err = ext4_journal_get_write_access(handle, gdb_bh);
+		if (err)
+			goto out;
+
+		if (reserved_gdb && ext4_bg_num_gdb(sb, group))
+			err = reserve_backup_gdb(handle, resize_inode, group);
+	} else
+		err = add_new_gdb(handle, resize_inode, group);
+
+out:
+	return err;
+}
+
 /* Add group descriptor data to an existing or new group descriptor block.
  * Ensure we handle all possible error conditions _before_ we start modifying
  * the filesystem, because we cannot abort the transaction and not have it
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 03/15] ext4: add a function which sets up a new group desc
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 01/15] ext4: add a function which extends a group without checking parameters Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 02/15] ext4: add a function which adds a new desc to a fs Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 04/15] ext4: add a function which updates super block Yongqiang Yang
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch adds a function named ext4_setup_new_desc() which sets
up a new group descriptor and whose code is sopied from ext4_group_add().

The function will be used by new resize implementation.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/resize.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 9a5486e..a50eab3 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -777,6 +777,61 @@ out:
 	return err;
 }
 
+/*
+ * ext4_setup_new_desc() sets up group descriptors specified by @input.
+ *
+ * @handle: journal handle
+ * @sb: super block
+ */
+static int ext4_setup_new_desc(handle_t *handle, struct super_block *sb,
+			       struct ext4_new_group_data *input)
+{
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	ext4_group_t group;
+	struct ext4_group_desc *gdp;
+	struct buffer_head *gdb_bh;
+	int gdb_off, gdb_num, err = 0;
+
+	group = input->group;
+
+	gdb_off = group % EXT4_DESC_PER_BLOCK(sb);
+	gdb_num = group / EXT4_DESC_PER_BLOCK(sb);
+
+	/*
+	 * get_write_access() has been called on gdb_bh by ext4_add_new_desc().
+	 */
+	gdb_bh = sbi->s_group_desc[gdb_num];
+	/* Update group descriptor block for new group */
+	gdp = (struct ext4_group_desc *)((char *)gdb_bh->b_data +
+				 gdb_off * EXT4_DESC_SIZE(sb));
+
+	memset(gdp, 0, EXT4_DESC_SIZE(sb));
+	 /* LV FIXME */
+	memset(gdp, 0, EXT4_DESC_SIZE(sb));
+	ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */
+	ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */
+	ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */
+	ext4_free_group_clusters_set(sb, gdp,
+				     EXT4_B2C(sbi, input->free_blocks_count));
+	ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
+	gdp->bg_flags = cpu_to_le16(EXT4_BG_INODE_ZEROED);
+	gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp);
+
+	err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh);
+	if (unlikely(err)) {
+		ext4_std_error(sb, err);
+		return err;
+	}
+
+	/*
+	 * We can allocate memory for mb_alloc based on the new group
+	 * descriptor
+	 */
+	err = ext4_mb_add_groupinfo(sb, group, gdp);
+
+	return err;
+}
+
 /* Add group descriptor data to an existing or new group descriptor block.
  * Ensure we handle all possible error conditions _before_ we start modifying
  * the filesystem, because we cannot abort the transaction and not have it
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 04/15] ext4: add a function which updates super block
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (2 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 03/15] ext4: add a function which sets up a new group desc Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 05/15] ext4: add a structure which will be used by 64bit-resize interface Yongqiang Yang
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch adds a function named ext4_update_super() which updates
super block and whose code is copied from ext4_group_add().

The function will be used by new resize implementation.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/resize.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index a50eab3..859b63f 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -832,6 +832,78 @@ static int ext4_setup_new_desc(handle_t *handle, struct super_block *sb,
 	return err;
 }
 
+/*
+ * ext4_update_super() updates super so that new the added group can be seen
+ *   by the filesystem.
+ *
+ * @sb: super block
+ */
+static void ext4_update_super(struct super_block *sb,
+			      struct ext4_new_group_data *input)
+{
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct ext4_super_block *es = sbi->s_es;
+
+	/*
+	 * Make the new blocks and inodes valid next.  We do this before
+	 * increasing the group count so that once the group is enabled,
+	 * all of its blocks and inodes are already valid.
+	 *
+	 * We always allocate group-by-group, then block-by-block or
+	 * inode-by-inode within a group, so enabling these
+	 * blocks/inodes before the group is live won't actually let us
+	 * allocate the new space yet.
+	 */
+	ext4_blocks_count_set(es, ext4_blocks_count(es) +
+		input->blocks_count);
+	le32_add_cpu(&es->s_inodes_count, EXT4_INODES_PER_GROUP(sb));
+
+	/*
+	 * We need to protect s_groups_count against other CPUs seeing
+	 * inconsistent state in the superblock.
+	 *
+	 * The precise rules we use are:
+	 *
+	 * * Writers must perform a smp_wmb() after updating all dependent
+	 *   data and before modifying the groups count
+	 *
+	 * * Readers must perform an smp_rmb() after reading the groups count
+	 *   and before reading any dependent data.
+	 *
+	 * NB. These rules can be relaxed when checking the group count
+	 * while freeing data, as we can only allocate from a block
+	 * group after serialising against the group count, and we can
+	 * only then free after serialising in turn against that
+	 * allocation.
+	 */
+	smp_wmb();
+
+	/* Update the global fs size fields */
+	sbi->s_groups_count++;
+
+	/* Update the reserved block counts only once the new group is
+	 * active. */
+	ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) +
+		input->reserved_blocks);
+
+	/* Update the free space counts */
+	percpu_counter_add(&sbi->s_freeclusters_counter,
+			   EXT4_B2C(sbi, input->free_blocks_count));
+	percpu_counter_add(&sbi->s_freeinodes_counter,
+			   EXT4_INODES_PER_GROUP(sb));
+
+	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
+	    sbi->s_log_groups_per_flex) {
+		ext4_group_t flex_group;
+		flex_group = ext4_flex_group(sbi, input->group);
+		atomic_add(EXT4_B2C(sbi, input->free_blocks_count),
+			   &sbi->s_flex_groups[flex_group].free_clusters);
+		atomic_add(EXT4_INODES_PER_GROUP(sb),
+			   &sbi->s_flex_groups[flex_group].free_inodes);
+	}
+
+}
+
 /* Add group descriptor data to an existing or new group descriptor block.
  * Ensure we handle all possible error conditions _before_ we start modifying
  * the filesystem, because we cannot abort the transaction and not have it
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 05/15] ext4: add a structure which will be used by 64bit-resize interface
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (3 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 04/15] ext4: add a function which updates super block Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 06/15] ext4: add a function which sets up group blocks of a flex groups Yongqiang Yang
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch adds a structure which will be used by 64bit-resize interface.
Two functions which allocate and destroy the structure respectively are
added.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/resize.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 55 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 859b63f..78f3bab 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -134,6 +134,61 @@ static int verify_group_input(struct super_block *sb,
 	return err;
 }
 
+/*
+ * ext4_new_flex_group_data is used by 64bit-resize interface to add a flex
+ * group each time.
+ */
+struct ext4_new_flex_group_data {
+	struct ext4_new_group_data *groups;	/* new_group_data for groups
+						   in the flex group */
+	__u16 *bg_flags;			/* block group flags of groups
+						   in @groups */
+	ext4_group_t count;			/* number of groups in @groups
+						 */
+};
+
+/*
+ * alloc_flex_gd() allocates a ext4_new_flex_group_data with size of
+ * @flexbg_size.
+ *
+ * Returns NULL on failure otherwise address of the allocated structure.
+ */
+static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned long flexbg_size)
+{
+	struct ext4_new_flex_group_data *flex_gd;
+
+	flex_gd = kmalloc(sizeof(*flex_gd), GFP_NOFS);
+	if (flex_gd == NULL)
+		goto out3;
+
+	flex_gd->count = flexbg_size;
+
+	flex_gd->groups = kmalloc(sizeof(struct ext4_new_group_data) *
+				  flexbg_size, GFP_NOFS);
+	if (flex_gd->groups == NULL)
+		goto out2;
+
+	flex_gd->bg_flags = kmalloc(flexbg_size * sizeof(__u16), GFP_NOFS);
+	if (flex_gd->bg_flags == NULL)
+		goto out1;
+
+	return flex_gd;
+
+out1:
+	kfree(flex_gd->groups);
+out2:
+	kfree(flex_gd);
+out3:
+	return NULL;
+}
+
+void free_flex_gd(struct ext4_new_flex_group_data *flex_gd)
+{
+	kfree(flex_gd->bg_flags);
+	kfree(flex_gd->groups);
+	kfree(flex_gd);
+}
+
 static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
 				  ext4_fsblk_t blk)
 {
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 06/15] ext4: add a function which sets up group blocks of a flex groups
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (4 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 05/15] ext4: add a structure which will be used by 64bit-resize interface Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 07/15] ext4: add a function which adds several group descriptors Yongqiang Yang
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch adds a function named setup_new_flex_group_blocks() which
sets up group blocks of a flex groups.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/ext4.h   |    8 ++
 fs/ext4/resize.c |  218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 226 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 604c200..a062ab3 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -511,6 +511,14 @@ struct ext4_new_group_data {
 	__u32 free_blocks_count;
 };
 
+/* Indexes used to index group tables in ext4_new_group_data */
+enum {
+	BLOCK_BITMAP = 0,	/* block bitmap */
+	INODE_BITMAP,		/* inode bitmap */
+	INODE_TABLE,		/* inode tables */
+	GROUP_TABLE_COUNT,
+};
+
 /*
  * Flags used by ext4_map_blocks()
  */
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 78f3bab..cdefa36 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -234,6 +234,224 @@ static int extend_or_restart_transaction(handle_t *handle, int thresh)
 }
 
 /*
+ * set_flexbg_block_bitmap() mark @count blocks starting from @block used.
+ *
+ * Helper function for ext4_setup_new_group_blocks() which set .
+ *
+ * @sb: super block
+ * @handle: journal handle
+ * @flex_gd: flex group data
+ */
+static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle,
+			struct ext4_new_flex_group_data *flex_gd,
+			ext4_fsblk_t block, ext4_group_t count)
+{
+	ext4_group_t count2;
+
+	ext4_debug("mark blocks [%llu/%u] used\n", block, count);
+	for (count2 = count; count > 0; count -= count2, block += count2) {
+		ext4_fsblk_t start;
+		struct buffer_head *bh;
+		ext4_group_t group;
+		int err;
+
+		ext4_get_group_no_and_offset(sb, block, &group, NULL);
+		start = ext4_group_first_block_no(sb, group);
+		group -= flex_gd->groups[0].group;
+
+		count2 = sb->s_blocksize * 8 - (block - start);
+		if (count2 > count)
+			count2 = count;
+
+		if (flex_gd->bg_flags[group] & EXT4_BG_BLOCK_UNINIT) {
+			BUG_ON(flex_gd->count > 1);
+			continue;
+		}
+
+		err = extend_or_restart_transaction(handle, 1);
+		if (err)
+			return err;
+
+		bh = sb_getblk(sb, flex_gd->groups[group].block_bitmap);
+		if (!bh)
+			return -EIO;
+
+		err = ext4_journal_get_write_access(handle, bh);
+		if (err)
+			return err;
+		ext4_debug("mark block bitmap %#04llx (+%llu/%u)\n", block,
+			   block - start, count2);
+		ext4_set_bits(bh->b_data, block - start, count2);
+
+		err = ext4_handle_dirty_metadata(handle, NULL, bh);
+		if (unlikely(err))
+			return err;
+		brelse(bh);
+	}
+
+	return 0;
+}
+
+/*
+ * Set up the block and inode bitmaps, and the inode table for the new groups.
+ * This doesn't need to be part of the main transaction, since we are only
+ * changing blocks outside the actual filesystem.  We still do journaling to
+ * ensure the recovery is correct in case of a failure just after resize.
+ * If any part of this fails, we simply abort the resize.
+ *
+ * setup_new_flex_group_blocks handles a flex group as follow:
+ *  1. copy super block and GDT, and initialize group tables if necessary.
+ *     In this step, we only set bits in blocks bitmaps for blocks taken by
+ *     super block and GDT.
+ *  2. allocate group tables in block bitmaps, that is, set bits in block
+ *     bitmap for blocks taken by group tables.
+ */
+static int setup_new_flex_group_blocks(struct super_block *sb,
+				struct ext4_new_flex_group_data *flex_gd)
+{
+	int group_table_count[] = {1, 1, EXT4_SB(sb)->s_itb_per_group};
+	ext4_fsblk_t start;
+	ext4_fsblk_t block;
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct ext4_super_block *es = sbi->s_es;
+	struct ext4_new_group_data *group_data = flex_gd->groups;
+	__u16 *bg_flags = flex_gd->bg_flags;
+	handle_t *handle;
+	ext4_group_t group, count;
+	struct buffer_head *bh = NULL;
+	int reserved_gdb, i, j, err = 0, err2;
+
+	BUG_ON(!flex_gd->count || !group_data ||
+	       group_data[0].group != sbi->s_groups_count);
+
+	reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
+
+	/* This transaction may be extended/restarted along the way */
+	handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+
+	group = group_data[0].group;
+	for (i = 0; i < flex_gd->count; i++, group++) {
+		unsigned long gdblocks;
+
+		gdblocks = ext4_bg_num_gdb(sb, group);
+		start = ext4_group_first_block_no(sb, group);
+
+		/* Copy all of the GDT blocks into the backup in this group */
+		for (j = 0, block = start + 1; j < gdblocks; j++, block++) {
+			struct buffer_head *gdb;
+
+			ext4_debug("update backup group %#04llx\n", block);
+			err = extend_or_restart_transaction(handle, 1);
+			if (err)
+				goto out;
+
+			gdb = sb_getblk(sb, block);
+			if (!gdb) {
+				err = -EIO;
+				goto out;
+			}
+
+			err = ext4_journal_get_write_access(handle, gdb);
+			if (err) {
+				brelse(gdb);
+				goto out;
+			}
+			memcpy(gdb->b_data, sbi->s_group_desc[j]->b_data,
+			       gdb->b_size);
+			set_buffer_uptodate(gdb);
+
+			err = ext4_handle_dirty_metadata(handle, NULL, gdb);
+			if (unlikely(err)) {
+				brelse(gdb);
+				goto out;
+			}
+			brelse(gdb);
+		}
+
+		/* Zero out all of the reserved backup group descriptor
+		 * table blocks
+		 */
+		if (ext4_bg_has_super(sb, group)) {
+			err = sb_issue_zeroout(sb, gdblocks + start + 1,
+					reserved_gdb, GFP_NOFS);
+			if (err)
+				goto out;
+		}
+
+		/* Online resize never initializes inode bitmaps
+		   and inode tables. */
+		BUG_ON(!(bg_flags[i] & EXT4_BG_INODE_UNINIT) ||
+			 bg_flags[i] & EXT4_BG_INODE_ZEROED);
+
+		if (bg_flags[i] & EXT4_BG_BLOCK_UNINIT)
+			continue;
+
+		/* Initialize block bitmap of the @group */
+		block = group_data[i].block_bitmap;
+		err = extend_or_restart_transaction(handle, 1);
+		if (err)
+			goto out;
+
+		bh = bclean(handle, sb, block);
+		if (IS_ERR(bh)) {
+			err = PTR_ERR(bh);
+			goto out;
+		}
+		if (ext4_bg_has_super(sb, group)) {
+			ext4_debug("mark backup superblock %#04llx (+0)\n",
+				   start);
+			ext4_set_bits(bh->b_data, 0, gdblocks + reserved_gdb +
+						     1);
+		}
+		ext4_mark_bitmap_end(group_data[i].blocks_count,
+				     sb->s_blocksize * 8, bh->b_data);
+		err = ext4_handle_dirty_metadata(handle, NULL, bh);
+		if (err)
+			goto out;
+		brelse(bh);
+	}
+	bh = NULL;
+
+	/* Mark group tables in block bitmap */
+	for (j = 0; j < GROUP_TABLE_COUNT; j++) {
+		count = group_table_count[j];
+		start = (&group_data[0].block_bitmap)[j];
+		block = start;
+		for (i = 1; i < flex_gd->count; i++) {
+			block += group_table_count[j];
+			if (block == (&group_data[i].block_bitmap)[j]) {
+				count += group_table_count[j];
+				continue;
+			}
+			err = set_flexbg_block_bitmap(sb, handle,
+						flex_gd, start, count);
+			if (err)
+				goto out;
+			count = group_table_count[j];
+			start = group_data[i].block_bitmap;
+			block = start;
+		}
+
+		if (count) {
+			err = set_flexbg_block_bitmap(sb, handle,
+						flex_gd, start, count);
+			if (err)
+				goto out;
+		}
+	}
+
+out:
+	brelse(bh);
+	err2 = ext4_journal_stop(handle);
+	if (err2 && !err)
+		err = err2;
+
+	return err;
+}
+
+/*
  * Set up the block and inode bitmaps, and the inode table for the new group.
  * This doesn't need to be part of the main transaction, since we are only
  * changing blocks outside the actual filesystem.  We still do journaling to
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 07/15] ext4: add a function which adds several group descriptors
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (5 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 06/15] ext4: add a function which sets up group blocks of a flex groups Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 08/15] ext4: add a function which sets up a flex groups each time Yongqiang Yang
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch adds a functon named ext4_add_new_descs() which adds
several group descriptors each time.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/resize.c |   25 +++++++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index cdefa36..bae5b4c 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1051,6 +1051,31 @@ out:
 }
 
 /*
+ * ext4_add_new_descs() adds @count group descriptor of groups
+ * starting at @group
+ *
+ * @handle: journal handle
+ * @sb; super block
+ * @group: the group no. of the first group desc to be added
+ * @resize_inode: the resize inode
+ * @count: number of group descriptors to be added
+ */
+static int ext4_add_new_descs(handle_t *handle, struct super_block *sb,
+			ext4_group_t group, struct inode *resize_inode,
+			ext4_group_t count)
+{
+	int i, err = 0;
+
+	for (i = 0; i < count; i++) {
+		err = ext4_add_new_desc(handle, sb, group + i, resize_inode);
+		if (err)
+			return err;
+	}
+
+	return err;
+}
+
+/*
  * ext4_setup_new_desc() sets up group descriptors specified by @input.
  *
  * @handle: journal handle
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 08/15] ext4: add a function which sets up a flex groups each time
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (6 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 07/15] ext4: add a function which adds several group descriptors Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 09/15] ext4: enable ext4_update_super() to handle a flex groups Yongqiang Yang
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch adds a function named ext4_setup_new_descs() which sets up
a flex groups each time.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
---
 fs/ext4/resize.c |   25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index bae5b4c..5223245 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1082,7 +1082,8 @@ static int ext4_add_new_descs(handle_t *handle, struct super_block *sb,
  * @sb: super block
  */
 static int ext4_setup_new_desc(handle_t *handle, struct super_block *sb,
-			       struct ext4_new_group_data *input)
+			       struct ext4_new_group_data *input,
+			       __u16 bg_flags)
 {
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	ext4_group_t group;
@@ -1112,7 +1113,7 @@ static int ext4_setup_new_desc(handle_t *handle, struct super_block *sb,
 	ext4_free_group_clusters_set(sb, gdp,
 				     EXT4_B2C(sbi, input->free_blocks_count));
 	ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
-	gdp->bg_flags = cpu_to_le16(EXT4_BG_INODE_ZEROED);
+	gdp->bg_flags = cpu_to_le16(bg_flags);
 	gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp);
 
 	err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh);
@@ -1131,6 +1132,26 @@ static int ext4_setup_new_desc(handle_t *handle, struct super_block *sb,
 }
 
 /*
+ * ext4_setup_new_descs setups group descriptors of a flex groups
+ */
+static int ext4_setup_new_descs(handle_t *handle, struct super_block *sb,
+				struct ext4_new_flex_group_data *flex_gd)
+{
+	struct ext4_new_group_data *group_data = flex_gd->groups;
+	__u16 *bg_flags = flex_gd->bg_flags;
+	int i, err = 0;
+
+	for (i = 0; i < flex_gd->count; i++) {
+		err = ext4_setup_new_desc(handle, sb, group_data + i,
+					  bg_flags[i]);
+		if (err)
+			return err;
+	}
+
+	return err;
+}
+
+/*
  * ext4_update_super() updates super so that new the added group can be seen
  *   by the filesystem.
  *
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 09/15] ext4: enable ext4_update_super() to handle a flex groups
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (7 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 08/15] ext4: add a function which sets up a flex groups each time Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 10/15] ext4: pass verify_reserved_gdb() the number of group decriptors Yongqiang Yang
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch enables ext4_update_super() to handle a flex groups.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/resize.c |   58 +++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 5223245..fdce84c 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1152,17 +1152,24 @@ static int ext4_setup_new_descs(handle_t *handle, struct super_block *sb,
 }
 
 /*
- * ext4_update_super() updates super so that new the added group can be seen
- *   by the filesystem.
+ * ext4_update_super() updates super block so that new added groups can be seen
+ * by the filesystem.
  *
  * @sb: super block
+ * @flex_gd: new added groups
  */
 static void ext4_update_super(struct super_block *sb,
-			      struct ext4_new_group_data *input)
+			     struct ext4_new_flex_group_data *flex_gd)
 {
+	ext4_fsblk_t blocks_count = 0;
+	ext4_fsblk_t free_blocks = 0;
+	ext4_fsblk_t reserved_blocks = 0;
+	struct ext4_new_group_data *group_data = flex_gd->groups;
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	struct ext4_super_block *es = sbi->s_es;
+	int i;
 
+	BUG_ON(flex_gd->count == 0 || group_data == NULL);
 	/*
 	 * Make the new blocks and inodes valid next.  We do this before
 	 * increasing the group count so that once the group is enabled,
@@ -1173,9 +1180,19 @@ static void ext4_update_super(struct super_block *sb,
 	 * blocks/inodes before the group is live won't actually let us
 	 * allocate the new space yet.
 	 */
-	ext4_blocks_count_set(es, ext4_blocks_count(es) +
-		input->blocks_count);
-	le32_add_cpu(&es->s_inodes_count, EXT4_INODES_PER_GROUP(sb));
+	for (i = 0; i < flex_gd->count; i++) {
+		blocks_count += group_data[i].blocks_count;
+		free_blocks += group_data[i].free_blocks_count;
+	}
+
+	reserved_blocks = ext4_r_blocks_count(es) * 100;
+	do_div(reserved_blocks, ext4_blocks_count(es));
+	reserved_blocks *= blocks_count;
+	do_div(reserved_blocks, 100);
+
+	ext4_blocks_count_set(es, ext4_blocks_count(es) + blocks_count);
+	le32_add_cpu(&es->s_inodes_count, EXT4_INODES_PER_GROUP(sb) *
+		     flex_gd->count);
 
 	/*
 	 * We need to protect s_groups_count against other CPUs seeing
@@ -1183,11 +1200,11 @@ static void ext4_update_super(struct super_block *sb,
 	 *
 	 * The precise rules we use are:
 	 *
-	 * * Writers must perform a smp_wmb() after updating all dependent
-	 *   data and before modifying the groups count
+	 * * Writers must perform a smp_wmb() after updating all
+	 *   dependent data and before modifying the groups count
 	 *
-	 * * Readers must perform an smp_rmb() after reading the groups count
-	 *   and before reading any dependent data.
+	 * * Readers must perform an smp_rmb() after reading the groups
+	 *   count and before reading any dependent data.
 	 *
 	 * NB. These rules can be relaxed when checking the group count
 	 * while freeing data, as we can only allocate from a block
@@ -1198,29 +1215,34 @@ static void ext4_update_super(struct super_block *sb,
 	smp_wmb();
 
 	/* Update the global fs size fields */
-	sbi->s_groups_count++;
+	sbi->s_groups_count += flex_gd->count;
 
 	/* Update the reserved block counts only once the new group is
 	 * active. */
 	ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) +
-		input->reserved_blocks);
+				reserved_blocks);
 
 	/* Update the free space counts */
 	percpu_counter_add(&sbi->s_freeclusters_counter,
-			   EXT4_B2C(sbi, input->free_blocks_count));
+			   EXT4_B2C(sbi, free_blocks));
 	percpu_counter_add(&sbi->s_freeinodes_counter,
-			   EXT4_INODES_PER_GROUP(sb));
+			   EXT4_INODES_PER_GROUP(sb) * flex_gd->count);
 
-	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
+	if (EXT4_HAS_INCOMPAT_FEATURE(sb,
+				      EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
 	    sbi->s_log_groups_per_flex) {
 		ext4_group_t flex_group;
-		flex_group = ext4_flex_group(sbi, input->group);
-		atomic_add(EXT4_B2C(sbi, input->free_blocks_count),
+		flex_group = ext4_flex_group(sbi, group_data[0].group);
+		atomic_add(EXT4_B2C(sbi, free_blocks),
 			   &sbi->s_flex_groups[flex_group].free_clusters);
-		atomic_add(EXT4_INODES_PER_GROUP(sb),
+		atomic_add(EXT4_INODES_PER_GROUP(sb) * flex_gd->count,
 			   &sbi->s_flex_groups[flex_group].free_inodes);
 	}
 
+	if (test_opt(sb, DEBUG))
+		printk(KERN_DEBUG "EXT4-fs: added group %u:"
+		       "%llu blocks(%llu free %llu reserved)\n", flex_gd->count,
+		       blocks_count, free_blocks, reserved_blocks);
 }
 
 /* Add group descriptor data to an existing or new group descriptor block.
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 10/15] ext4: pass verify_reserved_gdb() the number of group decriptors
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (8 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 09/15] ext4: enable ext4_update_super() to handle a flex groups Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 11/15] ext4: add a new function which allocates bitmaps and inode tables Yongqiang Yang
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

The 64bit resizer adds a flex group each time, so verify_reserved_gdb
can not use s_groups_count directly, it should use the number of group
decriptors before the added group.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/resize.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index fdce84c..f368190 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -624,10 +624,10 @@ static unsigned ext4_list_backups(struct super_block *sb, unsigned *three,
  * groups in current filesystem that have BACKUPS, or -ve error code.
  */
 static int verify_reserved_gdb(struct super_block *sb,
+			       ext4_group_t end,
 			       struct buffer_head *primary)
 {
 	const ext4_fsblk_t blk = primary->b_blocknr;
-	const ext4_group_t end = EXT4_SB(sb)->s_groups_count;
 	unsigned three = 1;
 	unsigned five = 5;
 	unsigned seven = 7;
@@ -702,7 +702,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode,
 	if (!gdb_bh)
 		return -EIO;
 
-	gdbackups = verify_reserved_gdb(sb, gdb_bh);
+	gdbackups = verify_reserved_gdb(sb, group, gdb_bh);
 	if (gdbackups < 0) {
 		err = gdbackups;
 		goto exit_bh;
@@ -865,7 +865,8 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode,
 			err = -EIO;
 			goto exit_bh;
 		}
-		if ((gdbackups = verify_reserved_gdb(sb, primary[res])) < 0) {
+		gdbackups = verify_reserved_gdb(sb, group, primary[res]);
+		if (gdbackups < 0) {
 			brelse(primary[res]);
 			err = gdbackups;
 			goto exit_bh;
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 11/15] ext4: add a new function which allocates bitmaps and inode tables
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (9 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 10/15] ext4: pass verify_reserved_gdb() the number of group decriptors Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 12/15] ext4: add a new function which adds a flex group to a fs Yongqiang Yang
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch adds a new function named ext4_allocates_group_table() which
allcoates block bitmaps, inode bitmaps and inode tables for a flex groups and is
used by resize code.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/resize.c |  111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 111 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index f368190..cb8296b 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -189,6 +189,117 @@ void free_flex_gd(struct ext4_new_flex_group_data *flex_gd)
 	kfree(flex_gd);
 }
 
+/*
+ * ext4_alloc_group_tables() allocates block bitmaps, inode bitmaps
+ * and inode tables for a flex group.
+ *
+ * This function is used by 64bit-resize.  Note that this function allocates
+ * group tables from the 1st group of groups contained by @flexgd, which may
+ * be a partial of a flex group.
+ *
+ * @sb: super block of fs to which the groups belongs
+ */
+static void ext4_alloc_group_tables(struct super_block *sb,
+				struct ext4_new_flex_group_data *flex_gd,
+				int flexbg_size)
+{
+	struct ext4_new_group_data *group_data = flex_gd->groups;
+	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+	ext4_fsblk_t start_blk;
+	ext4_fsblk_t last_blk;
+	ext4_group_t src_group;
+	ext4_group_t bb_index = 0;
+	ext4_group_t ib_index = 0;
+	ext4_group_t it_index = 0;
+	ext4_group_t group;
+	ext4_group_t last_group;
+	unsigned overhead;
+
+	BUG_ON(flex_gd->count == 0 || group_data == NULL);
+
+	src_group = group_data[0].group;
+	last_group  = src_group + flex_gd->count - 1;
+
+	BUG_ON((flexbg_size > 1) && ((src_group & ~(flexbg_size - 1)) !=
+	       (last_group & ~(flexbg_size - 1))));
+next_group:
+	group = group_data[0].group;
+	start_blk = ext4_group_first_block_no(sb, src_group);
+	last_blk = start_blk + group_data[src_group - group].blocks_count;
+
+	overhead = ext4_bg_has_super(sb, src_group) ?
+		   (1 + ext4_bg_num_gdb(sb, src_group) +
+		    le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
+
+	start_blk += overhead;
+
+	BUG_ON(src_group >= group_data[0].group + flex_gd->count);
+	/* We collect contiguous blocks as much as possible. */
+	src_group++;
+	for (; src_group <= last_group; src_group++)
+		if (!ext4_bg_has_super(sb, src_group))
+			last_blk += group_data[src_group - group].blocks_count;
+		else
+			break;
+
+	/* Allocate block bitmaps */
+	for (; bb_index < flex_gd->count; bb_index++) {
+		if (start_blk >= last_blk)
+			goto next_group;
+		group_data[bb_index].block_bitmap = start_blk++;
+		ext4_get_group_no_and_offset(sb, start_blk - 1, &group, NULL);
+		group -= group_data[0].group;
+		group_data[group].free_blocks_count--;
+		if (flexbg_size > 1)
+			flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
+	}
+
+	/* Allocate inode bitmaps */
+	for (; ib_index < flex_gd->count; ib_index++) {
+		if (start_blk >= last_blk)
+			goto next_group;
+		group_data[ib_index].inode_bitmap = start_blk++;
+		ext4_get_group_no_and_offset(sb, start_blk - 1, &group, NULL);
+		group -= group_data[0].group;
+		group_data[group].free_blocks_count--;
+		if (flexbg_size > 1)
+			flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
+	}
+
+	/* Allocate inode tables */
+	for (; it_index < flex_gd->count; it_index++) {
+		if (start_blk + EXT4_SB(sb)->s_itb_per_group > last_blk)
+			goto next_group;
+		group_data[it_index].inode_table = start_blk;
+		ext4_get_group_no_and_offset(sb, start_blk, &group, NULL);
+		group -= group_data[0].group;
+		group_data[group].free_blocks_count -=
+					EXT4_SB(sb)->s_itb_per_group;
+		if (flexbg_size > 1)
+			flex_gd->bg_flags[group] &= ~EXT4_BG_BLOCK_UNINIT;
+
+		start_blk += EXT4_SB(sb)->s_itb_per_group;
+	}
+
+	if (test_opt(sb, DEBUG)) {
+		int i;
+		group = group_data[0].group;
+
+		printk(KERN_DEBUG "EXT4-fs: adding a flex group with "
+		       "%d groups, flexbg size is %d:\n", flex_gd->count,
+		       flexbg_size);
+
+		for (i = 0; i < flex_gd->count; i++) {
+			printk(KERN_DEBUG "adding %s group %u: %u "
+			       "blocks (%d free)\n",
+			       ext4_bg_has_super(sb, group + i) ? "normal" :
+			       "no-super", group + i,
+			       group_data[i].blocks_count,
+			       group_data[i].free_blocks_count);
+		}
+	}
+}
+
 static struct buffer_head *bclean(handle_t *handle, struct super_block *sb,
 				  ext4_fsblk_t blk)
 {
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 12/15] ext4: add a new function which adds a flex group to a fs
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (10 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 11/15] ext4: add a new function which allocates bitmaps and inode tables Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 13/15] ext4: add new online resize interface Yongqiang Yang
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch adds a new function named ext4_flex_group_add() which adds a
flex group to a fs.  The function is used by 64bit-resize interface.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
---
 fs/ext4/resize.c |   82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index cb8296b..bfca158 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1357,6 +1357,88 @@ static void ext4_update_super(struct super_block *sb,
 		       blocks_count, free_blocks, reserved_blocks);
 }
 
+/* Add a flex group to an fs. Ensure we handle all possible error conditions
+ * _before_ we start modifying the filesystem, because we cannot abort the
+ * transaction and not have it write the data to disk.
+ */
+static int ext4_flex_group_add(struct super_block *sb,
+			       struct inode *resize_inode,
+			       struct ext4_new_flex_group_data *flex_gd)
+{
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct ext4_super_block *es = sbi->s_es;
+	ext4_fsblk_t o_blocks_count;
+	ext4_grpblk_t last;
+	ext4_group_t group;
+	handle_t *handle;
+	unsigned reserved_gdb;
+	int err = 0, err2 = 0, credit;
+
+	BUG_ON(!flex_gd->count || !flex_gd->groups || !flex_gd->bg_flags);
+
+	reserved_gdb = le16_to_cpu(es->s_reserved_gdt_blocks);
+	o_blocks_count = ext4_blocks_count(es);
+	ext4_get_group_no_and_offset(sb, o_blocks_count, &group, &last);
+	BUG_ON(last);
+
+	err = setup_new_flex_group_blocks(sb, flex_gd);
+	if (err)
+		goto exit;
+	/*
+	 * We will always be modifying at least the superblock and  GDT
+	 * block.  If we are adding a group past the last current GDT block,
+	 * we will also modify the inode and the dindirect block.  If we
+	 * are adding a group with superblock/GDT backups  we will also
+	 * modify each of the reserved GDT dindirect blocks.
+	 */
+	credit = flex_gd->count * 4 + reserved_gdb;
+	handle = ext4_journal_start_sb(sb, credit);
+	if (IS_ERR(handle)) {
+		err = PTR_ERR(handle);
+		goto exit;
+	}
+
+	err = ext4_journal_get_write_access(handle, sbi->s_sbh);
+	if (err)
+		goto exit_journal;
+
+	group = flex_gd->groups[0].group;
+	BUG_ON(group != EXT4_SB(sb)->s_groups_count);
+	err = ext4_add_new_descs(handle, sb, group,
+				resize_inode, flex_gd->count);
+	if (err)
+		goto exit_journal;
+
+	err = ext4_setup_new_descs(handle, sb, flex_gd);
+	if (err)
+		goto exit_journal;
+
+	ext4_update_super(sb, flex_gd);
+
+	err = ext4_handle_dirty_super(handle, sb);
+
+exit_journal:
+	err2 = ext4_journal_stop(handle);
+	if (!err)
+		err = err2;
+
+	if (!err) {
+		int i;
+		update_backups(sb, sbi->s_sbh->b_blocknr, (char *)es,
+			       sizeof(struct ext4_super_block));
+		for (i = 0; i < flex_gd->count; i++, group++) {
+			struct buffer_head *gdb_bh;
+			int gdb_num;
+			gdb_num = group / EXT4_BLOCKS_PER_GROUP(sb);
+			gdb_bh = sbi->s_group_desc[gdb_num];
+			update_backups(sb, gdb_bh->b_blocknr, gdb_bh->b_data,
+				       gdb_bh->b_size);
+		}
+	}
+exit:
+	return err;
+}
+
 /* Add group descriptor data to an existing or new group descriptor block.
  * Ensure we handle all possible error conditions _before_ we start modifying
  * the filesystem, because we cannot abort the transaction and not have it
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 13/15] ext4: add new online resize interface
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (11 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 12/15] ext4: add a new function which adds a flex group to a fs Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 14/15] ext4: let ext4_group_extend() use common code Yongqiang Yang
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch adds new online resize interface, whose input argument is a
64-bit integer indicating how many blocks there are in the resized fs.

In new resize impelmentation, all work like allocating group tables are done
by kernel side, so the new resize interface can support flex_bg feature and
prepares ground for suppoting resize with features like bigalloc and exclude
bitmap. Besides these, user-space tools just passes in the new number of blocks.

We delay initializing the bitmaps and inode tables of added groups if possible
and add multi groups (a flex groups) each time, so new resize is very fast like
mkfs.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
---
 Documentation/filesystems/ext4.txt |    7 ++
 fs/ext4/ext4.h                     |    2 +
 fs/ext4/ioctl.c                    |   39 ++++++++
 fs/ext4/resize.c                   |  175 ++++++++++++++++++++++++++++++++++++
 4 files changed, 223 insertions(+), 0 deletions(-)

diff --git a/Documentation/filesystems/ext4.txt b/Documentation/filesystems/ext4.txt
index 4917cf2..10ec463 100644
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -581,6 +581,13 @@ Table of Ext4 specific ioctls
 			      behaviour may change in the future as it is
 			      not necessary and has been done this way only
 			      for sake of simplicity.
+
+ EXT4_IOC_RESIZE_FS	      Resize the filesystem to a new size.  The number
+			      of blocks of resized filesystem is passed in via
+			      64 bit integer argument.  The kernel allocates
+			      bitmaps and inode table, the userspace tool thus
+			      just passes the new number of blocks.
+
 ..............................................................................
 
 References
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index a062ab3..477137f 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -583,6 +583,7 @@ enum {
  /* note ioctl 11 reserved for filesystem-independent FIEMAP ioctl */
 #define EXT4_IOC_ALLOC_DA_BLKS		_IO('f', 12)
 #define EXT4_IOC_MOVE_EXT		_IOWR('f', 15, struct move_extent)
+#define EXT4_IOC_RESIZE_FS		_IOW('f', 16, __u64)
 
 #if defined(__KERNEL__) && defined(CONFIG_COMPAT)
 /*
@@ -1932,6 +1933,7 @@ extern int ext4_group_add(struct super_block *sb,
 extern int ext4_group_extend(struct super_block *sb,
 				struct ext4_super_block *es,
 				ext4_fsblk_t n_blocks_count);
+extern int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count);
 
 /* super.c */
 extern void *ext4_kvmalloc(size_t size, gfp_t flags);
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index a567968..cfe95f2 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -331,6 +331,44 @@ mext_out:
 		return err;
 	}
 
+	case EXT4_IOC_RESIZE_FS: {
+		ext4_fsblk_t n_blocks_count;
+		struct super_block *sb = inode->i_sb;
+		int err = 0, err2 = 0;
+
+		if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
+			       EXT4_FEATURE_RO_COMPAT_BIGALLOC)) {
+			ext4_msg(sb, KERN_ERR,
+				 "Online resizing not supported with bigalloc");
+			return -EOPNOTSUPP;
+		}
+
+		err = ext4_resize_begin(sb);
+		if (err)
+			return err;
+
+		if (copy_from_user(&n_blocks_count, (__u64 __user *)arg,
+				   sizeof(__u64)))
+			return -EFAULT;
+
+		err = mnt_want_write(filp->f_path.mnt);
+		if (err)
+			return err;
+
+		err = ext4_resize_fs(sb, n_blocks_count);
+		if (EXT4_SB(sb)->s_journal) {
+			jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
+			err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
+			jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
+		}
+		if (err == 0)
+			err = err2;
+		mnt_drop_write(filp->f_path.mnt);
+		ext4_resize_end(sb);
+
+		return err;
+	}
+
 	case FITRIM:
 	{
 		struct request_queue *q = bdev_get_queue(sb->s_bdev);
@@ -429,6 +467,7 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	}
 	case EXT4_IOC_MOVE_EXT:
 	case FITRIM:
+	case EXT4_IOC_RESIZE_FS:
 		break;
 	default:
 		return -ENOIOCTLCMD;
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index bfca158..6e0af4b 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1439,6 +1439,68 @@ exit:
 	return err;
 }
 
+static int ext4_setup_next_flex_gd(struct super_block *sb,
+				    struct ext4_new_flex_group_data *flex_gd,
+				    ext4_fsblk_t n_blocks_count,
+				    unsigned long flexbg_size)
+{
+	struct ext4_super_block *es = EXT4_SB(sb)->s_es;
+	struct ext4_new_group_data *group_data = flex_gd->groups;
+	ext4_fsblk_t o_blocks_count;
+	ext4_group_t n_group;
+	ext4_group_t group;
+	ext4_group_t last_group;
+	ext4_grpblk_t last;
+	ext4_grpblk_t blocks_per_group;
+	unsigned long i;
+
+	blocks_per_group = EXT4_BLOCKS_PER_GROUP(sb);
+
+	o_blocks_count = ext4_blocks_count(es);
+
+	if (o_blocks_count == n_blocks_count)
+		return 0;
+
+	ext4_get_group_no_and_offset(sb, o_blocks_count, &group, &last);
+	BUG_ON(last);
+	ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &last);
+
+	last_group = group | (flexbg_size - 1);
+	if (last_group > n_group)
+		last_group = n_group;
+
+	flex_gd->count = last_group - group + 1;
+
+	for (i = 0; i < flex_gd->count; i++) {
+		int overhead;
+
+		group_data[i].group = group + i;
+		group_data[i].blocks_count = blocks_per_group;
+		overhead = ext4_bg_has_super(sb, group + i) ?
+			   (1 + ext4_bg_num_gdb(sb, group + i) +
+			    le16_to_cpu(es->s_reserved_gdt_blocks)) : 0;
+		group_data[i].free_blocks_count = blocks_per_group - overhead;
+		if (EXT4_HAS_RO_COMPAT_FEATURE(sb,
+					       EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
+			flex_gd->bg_flags[i] = EXT4_BG_BLOCK_UNINIT |
+					       EXT4_BG_INODE_UNINIT;
+	}
+
+	if (last_group == n_group &&
+	    EXT4_HAS_RO_COMPAT_FEATURE(sb,
+				       EXT4_FEATURE_RO_COMPAT_GDT_CSUM))
+		/* We need to initialize block bitmap of last group. */
+		flex_gd->bg_flags[i - 1] &= ~EXT4_BG_BLOCK_UNINIT;
+
+	if ((last_group == n_group) && (last != blocks_per_group - 1)) {
+		group_data[i - 1].blocks_count = last + 1;
+		group_data[i - 1].free_blocks_count -= blocks_per_group-
+					last - 1;
+	}
+
+	return 1;
+}
+
 /* Add group descriptor data to an existing or new group descriptor block.
  * Ensure we handle all possible error conditions _before_ we start modifying
  * the filesystem, because we cannot abort the transaction and not have it
@@ -1838,3 +1900,116 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
 exit_put:
 	return err;
 } /* ext4_group_extend */
+
+/*
+ * ext4_resize_fs() resizes a fs to new size specified by @n_blocks_count
+ *
+ * @sb: super block of the fs to be resized
+ * @n_blocks_count: the number of blocks resides in the resized fs
+ */
+int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
+{
+	struct ext4_new_flex_group_data *flex_gd = NULL;
+	struct ext4_sb_info *sbi = EXT4_SB(sb);
+	struct ext4_super_block *es = sbi->s_es;
+	struct buffer_head *bh;
+	struct inode *resize_inode;
+	ext4_fsblk_t o_blocks_count;
+	ext4_group_t o_group;
+	ext4_group_t n_group;
+	ext4_grpblk_t offset;
+	unsigned long n_desc_blocks;
+	unsigned long o_desc_blocks;
+	unsigned long desc_blocks;
+	int err = 0, flexbg_size = 1;
+
+	o_blocks_count = ext4_blocks_count(es);
+
+	if (test_opt(sb, DEBUG))
+		printk(KERN_DEBUG "EXT4-fs: resizing filesystem from %llu "
+		       "upto %llu blocks\n", o_blocks_count, n_blocks_count);
+
+	if (n_blocks_count < o_blocks_count) {
+		/* On-line shrinking not supported */
+		ext4_warning(sb, "can't shrink FS - resize aborted");
+		return -EINVAL;
+	}
+
+	if (n_blocks_count == o_blocks_count)
+		/* Nothing need to do */
+		return 0;
+
+	ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &offset);
+	ext4_get_group_no_and_offset(sb, o_blocks_count, &o_group, &offset);
+
+	n_desc_blocks = (n_group + EXT4_DESC_PER_BLOCK(sb)) /
+			EXT4_DESC_PER_BLOCK(sb);
+	o_desc_blocks = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) /
+			EXT4_DESC_PER_BLOCK(sb);
+	desc_blocks = n_desc_blocks - o_desc_blocks;
+
+	if (desc_blocks &&
+	    (!EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_RESIZE_INODE) ||
+	     le16_to_cpu(es->s_reserved_gdt_blocks) < desc_blocks)) {
+		ext4_warning(sb, "No reserved GDT blocks, can't resize");
+		return -EPERM;
+	}
+
+	resize_inode = ext4_iget(sb, EXT4_RESIZE_INO);
+	if (IS_ERR(resize_inode)) {
+		ext4_warning(sb, "Error opening resize inode");
+		return PTR_ERR(resize_inode);
+	}
+
+	/* See if the device is actually as big as what was requested */
+	bh = sb_bread(sb, n_blocks_count - 1);
+	if (!bh) {
+		ext4_warning(sb, "can't read last block, resize aborted");
+		return -ENOSPC;
+	}
+	brelse(bh);
+
+	if (offset != 0) {
+		/* extend the last group */
+		ext4_grpblk_t add;
+		add = EXT4_BLOCKS_PER_GROUP(sb) - offset;
+		err = ext4_group_extend_no_check(sb, o_blocks_count, add);
+		if (err)
+			goto out;
+	}
+
+	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
+	    es->s_log_groups_per_flex)
+		flexbg_size = 1 << es->s_log_groups_per_flex;
+
+	o_blocks_count = ext4_blocks_count(es);
+	if (o_blocks_count == n_blocks_count)
+		goto out;
+
+	flex_gd = alloc_flex_gd(flexbg_size);
+	if (flex_gd == NULL) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	/* Add flex groups. Note that a regular group is a
+	 * flex group with 1 group.
+	 */
+	while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count,
+					      flexbg_size)) {
+		ext4_alloc_group_tables(sb, flex_gd, flexbg_size);
+		err = ext4_flex_group_add(sb, resize_inode, flex_gd);
+		if (unlikely(err))
+			break;
+	}
+
+out:
+	if (flex_gd)
+		free_flex_gd(flex_gd);
+
+	iput(resize_inode);
+	if (test_opt(sb, DEBUG))
+		printk(KERN_DEBUG "EXT4-fs: resized filesystem from %llu "
+		       "upto %llu blocks\n", o_blocks_count, n_blocks_count);
+	return err;
+}
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 14/15] ext4: let ext4_group_extend() use common code
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (12 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 13/15] ext4: add new online resize interface Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19  9:57 ` [PATCH v4 15/15] ext4: let ext4_group_add() " Yongqiang Yang
  2011-11-19 18:13 ` [PATCH v4 0/15] ext4: add new online resize interface Andreas Dilger
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

ext4_group_extend_no_check() is moved out from ext4_group_extend(),
this patch lets ext4_group_extend() call ext4_group_extentd_no_check()
instead.

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
---
 fs/ext4/resize.c |   41 ++---------------------------------------
 1 files changed, 2 insertions(+), 39 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 6e0af4b..ba04e0b 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1804,8 +1804,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
 	ext4_grpblk_t last;
 	ext4_grpblk_t add;
 	struct buffer_head *bh;
-	handle_t *handle;
-	int err, err2;
+	int err;
 	ext4_group_t group;
 
 	o_blocks_count = ext4_blocks_count(es);
@@ -1861,43 +1860,7 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
 	}
 	brelse(bh);
 
-	/* We will update the superblock, one block bitmap, and
-	 * one group descriptor via ext4_free_blocks().
-	 */
-	handle = ext4_journal_start_sb(sb, 3);
-	if (IS_ERR(handle)) {
-		err = PTR_ERR(handle);
-		ext4_warning(sb, "error %d on journal start", err);
-		goto exit_put;
-	}
-
-	if ((err = ext4_journal_get_write_access(handle,
-						 EXT4_SB(sb)->s_sbh))) {
-		ext4_warning(sb, "error %d on journal write access", err);
-		ext4_journal_stop(handle);
-		goto exit_put;
-	}
-	ext4_blocks_count_set(es, o_blocks_count + add);
-	ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count,
-		   o_blocks_count + add);
-	/* We add the blocks to the bitmap and set the group need init bit */
-	err = ext4_group_add_blocks(handle, sb, o_blocks_count, add);
-	ext4_handle_dirty_super(handle, sb);
-	ext4_debug("freed blocks %llu through %llu\n", o_blocks_count,
-		   o_blocks_count + add);
-	err2 = ext4_journal_stop(handle);
-	if (!err && err2)
-		err = err2;
-
-	if (err)
-		goto exit_put;

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v4 15/15] ext4: let ext4_group_add() use common code
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (13 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 14/15] ext4: let ext4_group_extend() use common code Yongqiang Yang
@ 2011-11-19  9:57 ` Yongqiang Yang
  2011-11-19 18:13 ` [PATCH v4 0/15] ext4: add new online resize interface Andreas Dilger
  15 siblings, 0 replies; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-19  9:57 UTC (permalink / raw)
  To: tytso; +Cc: adilger, linux-ext4, Yongqiang Yang

From: Yongqiang Yang <xiaoqiangnk@gmail.com>

This patch lets ext4_group_add() call ext4_flex_group_add().

Signed-off-by: Yongqiang Yang <xiaoqiangnk@gmail.com>
---
 fs/ext4/resize.c |  309 ++----------------------------------------------------
 1 files changed, 10 insertions(+), 299 deletions(-)

diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index ba04e0b..2ca8fd0 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -563,137 +563,6 @@ out:
 }
 
 /*
- * Set up the block and inode bitmaps, and the inode table for the new group.
- * This doesn't need to be part of the main transaction, since we are only
- * changing blocks outside the actual filesystem.  We still do journaling to
- * ensure the recovery is correct in case of a failure just after resize.
- * If any part of this fails, we simply abort the resize.
- */
-static int setup_new_group_blocks(struct super_block *sb,
-				  struct ext4_new_group_data *input)
-{
-	struct ext4_sb_info *sbi = EXT4_SB(sb);
-	ext4_fsblk_t start = ext4_group_first_block_no(sb, input->group);
-	int reserved_gdb = ext4_bg_has_super(sb, input->group) ?
-		le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) : 0;
-	unsigned long gdblocks = ext4_bg_num_gdb(sb, input->group);
-	struct buffer_head *bh;
-	handle_t *handle;
-	ext4_fsblk_t block;
-	ext4_grpblk_t bit;
-	int i;
-	int err = 0, err2;
-
-	/* This transaction may be extended/restarted along the way */
-	handle = ext4_journal_start_sb(sb, EXT4_MAX_TRANS_DATA);
-
-	if (IS_ERR(handle))
-		return PTR_ERR(handle);
-
-	BUG_ON(input->group != sbi->s_groups_count);
-
-	/* Copy all of the GDT blocks into the backup in this group */
-	for (i = 0, bit = 1, block = start + 1;
-	     i < gdblocks; i++, block++, bit++) {
-		struct buffer_head *gdb;
-
-		ext4_debug("update backup group %#04llx (+%d)\n", block, bit);
-		err = extend_or_restart_transaction(handle, 1);
-		if (err)
-			goto exit_journal;
-
-		gdb = sb_getblk(sb, block);
-		if (!gdb) {
-			err = -EIO;
-			goto exit_journal;
-		}
-		if ((err = ext4_journal_get_write_access(handle, gdb))) {
-			brelse(gdb);
-			goto exit_journal;
-		}
-		memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
-		set_buffer_uptodate(gdb);
-		err = ext4_handle_dirty_metadata(handle, NULL, gdb);
-		if (unlikely(err)) {
-			brelse(gdb);
-			goto exit_journal;
-		}
-		brelse(gdb);
-	}
-
-	/* Zero out all of the reserved backup group descriptor table blocks */
-	ext4_debug("clear inode table blocks %#04llx -> %#04lx\n",
-			block, sbi->s_itb_per_group);
-	err = sb_issue_zeroout(sb, gdblocks + start + 1, reserved_gdb,
-			       GFP_NOFS);
-	if (err)
-		goto exit_journal;
-
-	err = extend_or_restart_transaction(handle, 2);
-	if (err)
-		goto exit_journal;
-
-	bh = bclean(handle, sb, input->block_bitmap);
-	if (IS_ERR(bh)) {
-		err = PTR_ERR(bh);
-		goto exit_journal;
-	}
-
-	if (ext4_bg_has_super(sb, input->group)) {
-		ext4_debug("mark backup group tables %#04llx (+0)\n", start);
-		ext4_set_bits(bh->b_data, 0, gdblocks + reserved_gdb + 1);
-	}
-
-	ext4_debug("mark block bitmap %#04llx (+%llu)\n", input->block_bitmap,
-		   input->block_bitmap - start);
-	ext4_set_bit(input->block_bitmap - start, bh->b_data);
-	ext4_debug("mark inode bitmap %#04llx (+%llu)\n", input->inode_bitmap,
-		   input->inode_bitmap - start);
-	ext4_set_bit(input->inode_bitmap - start, bh->b_data);
-
-	/* Zero out all of the inode table blocks */
-	block = input->inode_table;
-	ext4_debug("clear inode table blocks %#04llx -> %#04lx\n",
-			block, sbi->s_itb_per_group);
-	err = sb_issue_zeroout(sb, block, sbi->s_itb_per_group, GFP_NOFS);
-	if (err)
-		goto exit_bh;
-	ext4_set_bits(bh->b_data, input->inode_table - start,
-		      sbi->s_itb_per_group);
-
-
-	ext4_mark_bitmap_end(input->blocks_count, sb->s_blocksize * 8,
-			     bh->b_data);
-	err = ext4_handle_dirty_metadata(handle, NULL, bh);
-	if (unlikely(err)) {
-		ext4_std_error(sb, err);
-		goto exit_bh;
-	}
-	brelse(bh);
-	/* Mark unused entries in inode bitmap used */
-	ext4_debug("clear inode bitmap %#04llx (+%llu)\n",
-		   input->inode_bitmap, input->inode_bitmap - start);
-	if (IS_ERR(bh = bclean(handle, sb, input->inode_bitmap))) {
-		err = PTR_ERR(bh);
-		goto exit_journal;
-	}
-
-	ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), sb->s_blocksize * 8,
-			     bh->b_data);
-	err = ext4_handle_dirty_metadata(handle, NULL, bh);
-	if (unlikely(err))
-		ext4_std_error(sb, err);
-exit_bh:
-	brelse(bh);
-
-exit_journal:
-	if ((err2 = ext4_journal_stop(handle)) && !err)
-		err = err2;
-
-	return err;
-}
-
-/*
  * Iterate through the groups which hold BACKUP superblock/GDT copies in an
  * ext4 filesystem.  The counters should be initialized to 1, 5, and 7 before
  * calling this for the first time.  In a sparse filesystem it will be the
@@ -1516,16 +1385,15 @@ static int ext4_setup_next_flex_gd(struct super_block *sb,
  */
 int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 {
+	struct ext4_new_flex_group_data flex_gd;
 	struct ext4_sb_info *sbi = EXT4_SB(sb);
 	struct ext4_super_block *es = sbi->s_es;
 	int reserved_gdb = ext4_bg_has_super(sb, input->group) ?
 		le16_to_cpu(es->s_reserved_gdt_blocks) : 0;
-	struct buffer_head *primary = NULL;
-	struct ext4_group_desc *gdp;
 	struct inode *inode = NULL;
-	handle_t *handle;
 	int gdb_off, gdb_num;
-	int err, err2;
+	int err;
+	__u16 bg_flags = EXT4_BG_INODE_UNINIT;
 
 	gdb_num = input->group / EXT4_DESC_PER_BLOCK(sb);
 	gdb_off = input->group % EXT4_DESC_PER_BLOCK(sb);
@@ -1564,172 +1432,15 @@ int ext4_group_add(struct super_block *sb, struct ext4_new_group_data *input)
 	}
 
 
-	if ((err = verify_group_input(sb, input)))
-		goto exit_put;
-
-	if ((err = setup_new_group_blocks(sb, input)))
-		goto exit_put;
-
-	/*
-	 * We will always be modifying at least the superblock and a GDT
-	 * block.  If we are adding a group past the last current GDT block,
-	 * we will also modify the inode and the dindirect block.  If we
-	 * are adding a group with superblock/GDT backups  we will also
-	 * modify each of the reserved GDT dindirect blocks.
-	 */
-	handle = ext4_journal_start_sb(sb,
-				       ext4_bg_has_super(sb, input->group) ?
-				       3 + reserved_gdb : 4);
-	if (IS_ERR(handle)) {
-		err = PTR_ERR(handle);
-		goto exit_put;
-	}
-
-	if ((err = ext4_journal_get_write_access(handle, sbi->s_sbh)))
-		goto exit_journal;
-
-        /*
-         * We will only either add reserved group blocks to a backup group
-         * or remove reserved blocks for the first group in a new group block.
-         * Doing both would be mean more complex code, and sane people don't
-         * use non-sparse filesystems anymore.  This is already checked above.
-         */
-	if (gdb_off) {
-		primary = sbi->s_group_desc[gdb_num];
-		if ((err = ext4_journal_get_write_access(handle, primary)))
-			goto exit_journal;
-
-		if (reserved_gdb && ext4_bg_num_gdb(sb, input->group)) {
-			err = reserve_backup_gdb(handle, inode, input->group);
-			if (err)
-				goto exit_journal;
-		}
-	} else {
-		/*
-		 * Note that we can access new group descriptor block safely
-		 * only if add_new_gdb() succeeds.
-		 */
-		err = add_new_gdb(handle, inode, input->group);
-		if (err)
-			goto exit_journal;
-		primary = sbi->s_group_desc[gdb_num];
-	}
-
-        /*
-         * OK, now we've set up the new group.  Time to make it active.
-         *
-         * so we have to be safe wrt. concurrent accesses the group
-         * data.  So we need to be careful to set all of the relevant
-         * group descriptor data etc. *before* we enable the group.
-         *
-         * The key field here is sbi->s_groups_count: as long as
-         * that retains its old value, nobody is going to access the new
-         * group.
-         *
-         * So first we update all the descriptor metadata for the new
-         * group; then we update the total disk blocks count; then we
-         * update the groups count to enable the group; then finally we
-         * update the free space counts so that the system can start
-         * using the new disk blocks.
-         */
-
-	/* Update group descriptor block for new group */
-	gdp = (struct ext4_group_desc *)((char *)primary->b_data +
-					 gdb_off * EXT4_DESC_SIZE(sb));
-
-	memset(gdp, 0, EXT4_DESC_SIZE(sb));
-	ext4_block_bitmap_set(sb, gdp, input->block_bitmap); /* LV FIXME */
-	ext4_inode_bitmap_set(sb, gdp, input->inode_bitmap); /* LV FIXME */
-	ext4_inode_table_set(sb, gdp, input->inode_table); /* LV FIXME */
-	ext4_free_group_clusters_set(sb, gdp, input->free_blocks_count);
-	ext4_free_inodes_set(sb, gdp, EXT4_INODES_PER_GROUP(sb));
-	gdp->bg_flags = cpu_to_le16(EXT4_BG_INODE_ZEROED);
-	gdp->bg_checksum = ext4_group_desc_csum(sbi, input->group, gdp);
-
-	/*
-	 * We can allocate memory for mb_alloc based on the new group
-	 * descriptor
-	 */
-	err = ext4_mb_add_groupinfo(sb, input->group, gdp);
+	err = verify_group_input(sb, input);
 	if (err)
-		goto exit_journal;
-
-	/*
-	 * Make the new blocks and inodes valid next.  We do this before
-	 * increasing the group count so that once the group is enabled,
-	 * all of its blocks and inodes are already valid.
-	 *
-	 * We always allocate group-by-group, then block-by-block or
-	 * inode-by-inode within a group, so enabling these
-	 * blocks/inodes before the group is live won't actually let us
-	 * allocate the new space yet.
-	 */
-	ext4_blocks_count_set(es, ext4_blocks_count(es) +
-		input->blocks_count);
-	le32_add_cpu(&es->s_inodes_count, EXT4_INODES_PER_GROUP(sb));
-
-	/*
-	 * We need to protect s_groups_count against other CPUs seeing
-	 * inconsistent state in the superblock.
-	 *
-	 * The precise rules we use are:
-	 *
-	 * * Writers must perform a smp_wmb() after updating all dependent
-	 *   data and before modifying the groups count
-	 *
-	 * * Readers must perform an smp_rmb() after reading the groups count
-	 *   and before reading any dependent data.
-	 *
-	 * NB. These rules can be relaxed when checking the group count
-	 * while freeing data, as we can only allocate from a block
-	 * group after serialising against the group count, and we can
-	 * only then free after serialising in turn against that
-	 * allocation.
-	 */
-	smp_wmb();
-
-	/* Update the global fs size fields */
-	sbi->s_groups_count++;
-
-	err = ext4_handle_dirty_metadata(handle, NULL, primary);
-	if (unlikely(err)) {
-		ext4_std_error(sb, err);
-		goto exit_journal;
-	}
-
-	/* Update the reserved block counts only once the new group is
-	 * active. */
-	ext4_r_blocks_count_set(es, ext4_r_blocks_count(es) +
-		input->reserved_blocks);
-
-	/* Update the free space counts */
-	percpu_counter_add(&sbi->s_freeclusters_counter,
-			   EXT4_B2C(sbi, input->free_blocks_count));
-	percpu_counter_add(&sbi->s_freeinodes_counter,
-			   EXT4_INODES_PER_GROUP(sb));
-
-	if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
-	    sbi->s_log_groups_per_flex) {
-		ext4_group_t flex_group;
-		flex_group = ext4_flex_group(sbi, input->group);
-		atomic_add(EXT4_B2C(sbi, input->free_blocks_count),
-			   &sbi->s_flex_groups[flex_group].free_clusters);
-		atomic_add(EXT4_INODES_PER_GROUP(sb),
-			   &sbi->s_flex_groups[flex_group].free_inodes);
-	}

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v4 0/15] ext4: add new online resize interface
  2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
                   ` (14 preceding siblings ...)
  2011-11-19  9:57 ` [PATCH v4 15/15] ext4: let ext4_group_add() " Yongqiang Yang
@ 2011-11-19 18:13 ` Andreas Dilger
  2011-11-20  3:14   ` Yongqiang Yang
  15 siblings, 1 reply; 19+ messages in thread
From: Andreas Dilger @ 2011-11-19 18:13 UTC (permalink / raw)
  To: Yongqiang Yang; +Cc: tytso, adilger, linux-ext4

On 2011-11-19, at 2:57, Yongqiang Yang <xiaoqiangnk@gmail.com> wrote:
> This patch series adds new resize implementation to ext4.
> 
> -- What's new resize implementation?
>   It is a new online resize interface for ext4.  It can be used via
>   ioctl with EXT4_IOC_RESIZE_FS and a 64 bit integer indicating size
>   of the resized fs in block.
> 
> -- Difference between current resize and new resize.
>   New resize lets kernel do all work, like allocating bitmaps and
>   inode tables and can support flex_bg and BLOCK_UNINIT features.
>   Besides these, new resize is much faster than current resize.
> 
>   Below are benchmarks I made on my personal computer, fses with
>   flex_bg size = 16 were resized to 230GB evry time. The first
>   row shows the size of a fs from which the fs was resized to 230GB.
>   The datas were collected by 'time resize2fs'.
> 
>                      new resize
>                20GB          50GB      100GB
>      real    0m3.558s     0m2.891s    0m0.394s
>      user    0m0.004s     0m0.000s    0m0.394s
>      sys     0m0.048s     0m0.048s    0m0.028s
> 
>                      current resize
>                20GB          50GB      100GB
>      real    5m2.770s     4m43.757s  3m14.840s
>      user    0m0.040s     0m0.032s   0m0.024s
>      sys     0m0.464s     0m0.432s   0m0.324s

These stats must be backward, because resizing 20GB takes more time than resizing 100GB. 

>   According to data above, new resize is faster than current resize in both
>   user and sys time.  New resize performs well in sys time, because it
>   supports BLOCK_UNINIT and adds multi-groups each time.
> 
> -- About supporting new features.
>   YES! New resize can support new feature like bigalloc and exclude bitmap
>   easily.  Because it lets kernel do all work.
> 
> V3->V4:
>   rename __ext4_group_extend to ext4_group_extend_no_check.
> 
> V2->V3:
>   initialize block bitmap of last group.
>   remove code initalizing inode bitmap and inode tables.
> 
> Yongqiang.
> 
> git diff --stat
> 
> Documentation/filesystems/ext4.txt |    7 +
> fs/ext4/ext4.h                     |   10 +
> fs/ext4/ioctl.c                    |   39 ++
> fs/ext4/resize.c                   | 1167 +++++++++++++++++++++++++++---------
> 4 files changed, 942 insertions(+), 281 deletions(-)
> 
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v4 0/15] ext4: add new online resize interface
  2011-11-19 18:13 ` [PATCH v4 0/15] ext4: add new online resize interface Andreas Dilger
@ 2011-11-20  3:14   ` Yongqiang Yang
  2011-11-20 17:15     ` Andreas Dilger
  0 siblings, 1 reply; 19+ messages in thread
From: Yongqiang Yang @ 2011-11-20  3:14 UTC (permalink / raw)
  To: Andreas Dilger; +Cc: tytso, adilger, linux-ext4

On Sun, Nov 20, 2011 at 2:13 AM, Andreas Dilger <aedilger@gmail.com> wrote:
> On 2011-11-19, at 2:57, Yongqiang Yang <xiaoqiangnk@gmail.com> wrote:
>> This patch series adds new resize implementation to ext4.
>>
>> -- What's new resize implementation?
>>   It is a new online resize interface for ext4.  It can be used via
>>   ioctl with EXT4_IOC_RESIZE_FS and a 64 bit integer indicating size
>>   of the resized fs in block.
>>
>> -- Difference between current resize and new resize.
>>   New resize lets kernel do all work, like allocating bitmaps and
>>   inode tables and can support flex_bg and BLOCK_UNINIT features.
>>   Besides these, new resize is much faster than current resize.
>>
>>   Below are benchmarks I made on my personal computer, fses with
>>   flex_bg size = 16 were resized to 230GB evry time. The first
>>   row shows the size of a fs from which the fs was resized to 230GB.
>>   The datas were collected by 'time resize2fs'.
>>
>>                      new resize
>>                20GB          50GB      100GB
>>      real    0m3.558s     0m2.891s    0m0.394s
>>      user    0m0.004s     0m0.000s    0m0.394s
>>      sys     0m0.048s     0m0.048s    0m0.028s
>>
>>                      current resize
>>                20GB          50GB      100GB
>>      real    5m2.770s     4m43.757s  3m14.840s
>>      user    0m0.040s     0m0.032s   0m0.024s
>>      sys     0m0.464s     0m0.432s   0m0.324s
>
> These stats must be backward, because resizing 20GB takes more time than resizing 100GB.
Every time, the filesystem was resized from 20/50/100GB to 230GB, so
resizing 20GB should takes more time than resizing 100GB.   I am not
sure what you meant.

Yongqiang.
>
>>   According to data above, new resize is faster than current resize in both
>>   user and sys time.  New resize performs well in sys time, because it
>>   supports BLOCK_UNINIT and adds multi-groups each time.
>>
>> -- About supporting new features.
>>   YES! New resize can support new feature like bigalloc and exclude bitmap
>>   easily.  Because it lets kernel do all work.
>>
>> V3->V4:
>>   rename __ext4_group_extend to ext4_group_extend_no_check.
>>
>> V2->V3:
>>   initialize block bitmap of last group.
>>   remove code initalizing inode bitmap and inode tables.
>>
>> Yongqiang.
>>
>> git diff --stat
>>
>> Documentation/filesystems/ext4.txt |    7 +
>> fs/ext4/ext4.h                     |   10 +
>> fs/ext4/ioctl.c                    |   39 ++
>> fs/ext4/resize.c                   | 1167 +++++++++++++++++++++++++++---------
>> 4 files changed, 942 insertions(+), 281 deletions(-)
>>
>>
>



-- 
Best Wishes
Yongqiang Yang
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v4 0/15] ext4: add new online resize interface
  2011-11-20  3:14   ` Yongqiang Yang
@ 2011-11-20 17:15     ` Andreas Dilger
  0 siblings, 0 replies; 19+ messages in thread
From: Andreas Dilger @ 2011-11-20 17:15 UTC (permalink / raw)
  To: Yongqiang Yang; +Cc: tytso, adilger, linux-ext4

On 2011-11-19, at 20:14, Yongqiang Yang <xiaoqiangnk@gmail.com> wrote:

> On Sun, Nov 20, 2011 at 2:13 AM, Andreas Dilger <aedilger@gmail.com> wrote:
>> On 2011-11-19, at 2:57, Yongqiang Yang <xiaoqiangnk@gmail.com> wrote:
>>> 
>>>   Below are benchmarks I made on my personal computer, fses with
>>>   flex_bg size = 16 were resized to 230GB evry time. The first
>>>   row shows the size of a fs from which the fs was resized to 230GB.
>>>   The datas were collected by 'time resize2fs'.
>>> 
>>>                      new resize
>>>                20GB          50GB      100GB
>>>      real    0m3.558s     0m2.891s    0m0.394s
>>>      user    0m0.004s     0m0.000s    0m0.394s
>>>      sys     0m0.048s     0m0.048s    0m0.028s
>>> 
>>>                      current resize
>>>                20GB          50GB      100GB
>>>      real    5m2.770s     4m43.757s  3m14.840s
>>>      user    0m0.040s     0m0.032s   0m0.024s
>>>      sys     0m0.464s     0m0.432s   0m0.324s
>> 
>> These stats must be backward, because resizing 20GB takes more time than resizing 100GB.
> 
> Every time, the filesystem was resized from 20/50/100GB to 230GB, so
> resizing 20GB should takes more time than resizing 100GB.   I am not
> sure what you meant.

Sorry, I didn't read closely enough. I thought it was resizing by the given amount. 

Cheers, Andreas

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2011-11-20 17:15 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-19  9:57 [PATCH v4 0/15] ext4: add new online resize interface Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 01/15] ext4: add a function which extends a group without checking parameters Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 02/15] ext4: add a function which adds a new desc to a fs Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 03/15] ext4: add a function which sets up a new group desc Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 04/15] ext4: add a function which updates super block Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 05/15] ext4: add a structure which will be used by 64bit-resize interface Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 06/15] ext4: add a function which sets up group blocks of a flex groups Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 07/15] ext4: add a function which adds several group descriptors Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 08/15] ext4: add a function which sets up a flex groups each time Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 09/15] ext4: enable ext4_update_super() to handle a flex groups Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 10/15] ext4: pass verify_reserved_gdb() the number of group decriptors Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 11/15] ext4: add a new function which allocates bitmaps and inode tables Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 12/15] ext4: add a new function which adds a flex group to a fs Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 13/15] ext4: add new online resize interface Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 14/15] ext4: let ext4_group_extend() use common code Yongqiang Yang
2011-11-19  9:57 ` [PATCH v4 15/15] ext4: let ext4_group_add() " Yongqiang Yang
2011-11-19 18:13 ` [PATCH v4 0/15] ext4: add new online resize interface Andreas Dilger
2011-11-20  3:14   ` Yongqiang Yang
2011-11-20 17:15     ` Andreas Dilger

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.