* [PATCH 1/2] - ext3: fix setup_new_group_blocks locking
@ 2007-10-01 19:24 ` Eric Sandeen
2007-10-02 5:42 ` Andreas Dilger
0 siblings, 1 reply; 5+ messages in thread
From: Eric Sandeen @ 2007-10-01 19:24 UTC (permalink / raw)
To: ext4 development
setup_new_group_blocks() manipulates the group descriptor block bh
under the block_bitmap bh's lock. It shouldn't matter since nobody
but resize should be touching these blocks, but it's worth fixing up.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Index: linux-2.6.23-rc7/fs/ext3/resize.c
===================================================================
--- linux-2.6.23-rc7.orig/fs/ext3/resize.c
+++ linux-2.6.23-rc7/fs/ext3/resize.c
@@ -212,10 +212,10 @@ static int setup_new_group_blocks(struct
brelse(gdb);
goto exit_bh;
}
- lock_buffer(bh);
- memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size);
+ lock_buffer(gdb);
+ memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
set_buffer_uptodate(gdb);
- unlock_buffer(bh);
+ unlock_buffer(gdb);
ext3_journal_dirty_metadata(handle, gdb);
ext3_set_bit(bit, bh->b_data);
brelse(gdb);
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] - ext3: lighten up resize transaction requirements
@ 2007-10-01 19:24 ` Eric Sandeen
2007-10-01 19:24 ` [PATCH 1/2] - ext3: fix setup_new_group_blocks locking Eric Sandeen
0 siblings, 1 reply; 5+ messages in thread
From: Eric Sandeen @ 2007-10-01 19:24 UTC (permalink / raw)
To: ext4 development; +Cc: Andrew Morton
When resizing online, setup_new_group_blocks attempts to reserve a
potentially very large transaction, depending on the current filesystem
geometry. For some journal sizes, there may not be enough room for this
transaction, and the online resize will fail.
The patch below resizes & restarts the transaction as necessary while
setting up the new group, and should work with even the smallest journal.
Tested with something like:
[root@newbox ~]# dd if=/dev/zero of=fsfile bs=1024 count=32768
[root@newbox ~]# mkfs.ext3 -b 1024 fsfile 16384
[root@newbox ~]# mount -o loop fsfile mnt/
[root@newbox ~]# resize2fs /dev/loop0
resize2fs 1.40.2 (12-Jul-2007)
Filesystem at /dev/loop0 is mounted on /root/mnt; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 1
Performing an on-line resize of /dev/loop0 to 32768 (1k) blocks.
resize2fs: No space left on device While trying to add group #2
[root@newbox ~]# dmesg | tail -n 1
JBD: resize2fs wants too many credits (258 > 256)
[root@newbox ~]#
With the below change, it works.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Acked-by: Andreas Dilger <adilger@clusterfs.com>
Index: linux-2.6.23-rc7/fs/ext3/resize.c
===================================================================
--- linux-2.6.23-rc7.orig/fs/ext3/resize.c
+++ linux-2.6.23-rc7/fs/ext3/resize.c
@@ -154,6 +154,32 @@ static void mark_bitmap_end(int start_bi
}
/*
+ * If we have fewer than thresh credits, extend by EXT3_MAX_TRANS_DATA.
+ * If that fails, restart the transaction & regain write access for the
+ * buffer head which is used for block_bitmap modifications.
+ */
+static int extend_or_restart_transaction(handle_t *handle, int thresh,
+ struct buffer_head *bh)
+{
+ int err;
+
+ if (handle->h_buffer_credits >= thresh)
+ return 0;
+
+ err = ext3_journal_extend(handle, EXT3_MAX_TRANS_DATA);
+ if (err < 0)
+ return err;
+ if (err) {
+ if ((err = ext3_journal_restart(handle, EXT3_MAX_TRANS_DATA)))
+ return err;
+ if ((err = ext3_journal_get_write_access(handle, bh)))
+ return err;
+ }
+
+ return 0;
+}
+
+/*
* 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
@@ -175,8 +201,9 @@ static int setup_new_group_blocks(struct
int i;
int err = 0, err2;
- handle = ext3_journal_start_sb(sb, reserved_gdb + gdblocks +
- 2 + sbi->s_itb_per_group);
+ /* This transaction may be extended/restarted along the way */
+ handle = ext3_journal_start_sb(sb, EXT3_MAX_TRANS_DATA);
+
if (IS_ERR(handle))
return PTR_ERR(handle);
@@ -203,6 +230,9 @@ static int setup_new_group_blocks(struct
ext3_debug("update backup group %#04lx (+%d)\n", block, bit);
+ if ((err = extend_or_restart_transaction(handle, 1, bh)))
+ goto exit_bh;
+
gdb = sb_getblk(sb, block);
if (!gdb) {
err = -EIO;
@@ -228,6 +258,9 @@ static int setup_new_group_blocks(struct
ext3_debug("clear reserved block %#04lx (+%d)\n", block, bit);
+ if ((err = extend_or_restart_transaction(handle, 1, bh)))
+ goto exit_bh;
+
if (IS_ERR(gdb = bclean(handle, sb, block))) {
err = PTR_ERR(bh);
goto exit_bh;
@@ -249,6 +282,10 @@ static int setup_new_group_blocks(struct
struct buffer_head *it;
ext3_debug("clear inode block %#04lx (+%d)\n", block, bit);
+
+ if ((err = extend_or_restart_transaction(handle, 1, bh)))
+ goto exit_bh;
+
if (IS_ERR(it = bclean(handle, sb, block))) {
err = PTR_ERR(it);
goto exit_bh;
@@ -257,6 +294,10 @@ static int setup_new_group_blocks(struct
brelse(it);
ext3_set_bit(bit, bh->b_data);
}
+
+ if ((err = extend_or_restart_transaction(handle, 2, bh)))
+ goto exit_bh;
+
mark_bitmap_end(input->blocks_count, EXT3_BLOCKS_PER_GROUP(sb),
bh->b_data);
ext3_journal_dirty_metadata(handle, bh);
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] - ext4: fix setup_new_group_blocks locking
@ 2007-10-01 19:25 ` Eric Sandeen
2007-10-01 19:24 ` [PATCH 2/2] - ext3: lighten up resize transaction requirements Eric Sandeen
0 siblings, 1 reply; 5+ messages in thread
From: Eric Sandeen @ 2007-10-01 19:25 UTC (permalink / raw)
To: ext4 development; +Cc: Theodore Tso, Mingming Cao
setup_new_group_blocks() manipulates the group descriptor block bh
under the block_bitmap bh's lock. It shouldn't matter since nobody
but resize should be touching these blocks, but it's worth fixing up.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Index: linux-2.6.23-rc7/fs/ext4/resize.c
===================================================================
--- linux-2.6.23-rc7.orig/fs/ext4/resize.c
+++ linux-2.6.23-rc7/fs/ext4/resize.c
@@ -218,10 +218,10 @@ static int setup_new_group_blocks(struct
brelse(gdb);
goto exit_bh;
}
- lock_buffer(bh);
- memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size);
+ lock_buffer(gdb);
+ memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, gdb->b_size);
set_buffer_uptodate(gdb);
- unlock_buffer(bh);
+ unlock_buffer(gdb);
ext4_journal_dirty_metadata(handle, gdb);
ext4_set_bit(bit, bh->b_data);
brelse(gdb);
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] - ext4: lighten up resize transaction requirements
@ 2007-10-01 19:25 Eric Sandeen
2007-10-01 19:25 ` [PATCH 1/2] - ext4: fix setup_new_group_blocks locking Eric Sandeen
0 siblings, 1 reply; 5+ messages in thread
From: Eric Sandeen @ 2007-10-01 19:25 UTC (permalink / raw)
To: ext4 development; +Cc: Theodore Tso, Mingming Cao
When resizing online, setup_new_group_blocks attempts to reserve a
potentially very large transaction, depending on the current filesystem
geometry. For some journal sizes, there may not be enough room for this
transaction, and the online resize will fail.
The patch below resizes & restarts the transaction as necessary while
setting up the new group, and should work with even the smallest journal.
Tested with something like:
[root@newbox ~]# dd if=/dev/zero of=fsfile bs=1024 count=32768
[root@newbox ~]# mkfs.ext3 -b 1024 fsfile 16384
[root@newbox ~]# mount -o loop fsfile mnt/
[root@newbox ~]# resize2fs /dev/loop0
resize2fs 1.40.2 (12-Jul-2007)
Filesystem at /dev/loop0 is mounted on /root/mnt; on-line resizing required
old desc_blocks = 1, new_desc_blocks = 1
Performing an on-line resize of /dev/loop0 to 32768 (1k) blocks.
resize2fs: No space left on device While trying to add group #2
[root@newbox ~]# dmesg | tail -n 1
JBD: resize2fs wants too many credits (258 > 256)
[root@newbox ~]#
With the below change, it works.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Acked-by: Andreas Dilger <adilger@clusterfs.com>
Index: linux-2.6.23-rc7/fs/ext4/resize.c
===================================================================
--- linux-2.6.23-rc7.orig/fs/ext4/resize.c
+++ linux-2.6.23-rc7/fs/ext4/resize.c
@@ -160,6 +160,32 @@ static void mark_bitmap_end(int start_bi
}
/*
+ * If we have fewer than thresh credits, extend by EXT4_MAX_TRANS_DATA.
+ * If that fails, restart the transaction & regain write access for the
+ * buffer head which is used for block_bitmap modifications.
+ */
+static int extend_or_restart_transaction(handle_t *handle, int thresh,
+ struct buffer_head *bh)
+{
+ int err;
+
+ if (handle->h_buffer_credits >= thresh)
+ return 0;
+
+ err = ext4_journal_extend(handle, EXT4_MAX_TRANS_DATA);
+ if (err < 0)
+ return err;
+ if (err) {
+ if ((err = ext4_journal_restart(handle, EXT4_MAX_TRANS_DATA)))
+ return err;
+ if ((err = ext4_journal_get_write_access(handle, bh)))
+ return err;
+ }
+
+ return 0;
+}
+
+/*
* 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
@@ -181,8 +207,9 @@ static int setup_new_group_blocks(struct
int i;
int err = 0, err2;
- handle = ext4_journal_start_sb(sb, reserved_gdb + gdblocks +
- 2 + sbi->s_itb_per_group);
+ /* 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);
@@ -209,6 +236,9 @@ static int setup_new_group_blocks(struct
ext4_debug("update backup group %#04lx (+%d)\n", block, bit);
+ if ((err = extend_or_restart_transaction(handle, 1, bh)))
+ goto exit_bh;
+
gdb = sb_getblk(sb, block);
if (!gdb) {
err = -EIO;
@@ -234,6 +264,9 @@ static int setup_new_group_blocks(struct
ext4_debug("clear reserved block %#04lx (+%d)\n", block, bit);
+ if ((err = extend_or_restart_transaction(handle, 1, bh)))
+ goto exit_bh;
+
if (IS_ERR(gdb = bclean(handle, sb, block))) {
err = PTR_ERR(bh);
goto exit_bh;
@@ -255,6 +288,10 @@ static int setup_new_group_blocks(struct
struct buffer_head *it;
ext4_debug("clear inode block %#04lx (+%d)\n", block, bit);
+
+ if ((err = extend_or_restart_transaction(handle, 1, bh)))
+ goto exit_bh;
+
if (IS_ERR(it = bclean(handle, sb, block))) {
err = PTR_ERR(it);
goto exit_bh;
@@ -263,6 +300,10 @@ static int setup_new_group_blocks(struct
brelse(it);
ext4_set_bit(bit, bh->b_data);
}
+
+ if ((err = extend_or_restart_transaction(handle, 2, bh)))
+ goto exit_bh;
+
mark_bitmap_end(input->blocks_count, EXT4_BLOCKS_PER_GROUP(sb),
bh->b_data);
ext4_journal_dirty_metadata(handle, bh);
@@ -290,7 +331,6 @@ exit_journal:
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
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] - ext3: fix setup_new_group_blocks locking
2007-10-01 19:24 ` [PATCH 1/2] - ext3: fix setup_new_group_blocks locking Eric Sandeen
@ 2007-10-02 5:42 ` Andreas Dilger
0 siblings, 0 replies; 5+ messages in thread
From: Andreas Dilger @ 2007-10-02 5:42 UTC (permalink / raw)
To: Eric Sandeen; +Cc: ext4 development, Andrew Morton, Theodore Tso, Mingming Cao
On Oct 01, 2007 14:24 -0500, Eric Sandeen wrote:
> setup_new_group_blocks() manipulates the group descriptor block bh
> under the block_bitmap bh's lock. It shouldn't matter since nobody
> but resize should be touching these blocks, but it's worth fixing up.
>
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Acked-by; Andreas Dilger <adilger@clusterfs.com>
Cheers, Andreas
--
Andreas Dilger
Principal Software Engineer
Cluster File Systems, Inc.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-10-02 5:42 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-10-01 19:25 [PATCH 2/2] - ext4: lighten up resize transaction requirements Eric Sandeen
2007-10-01 19:25 ` [PATCH 1/2] - ext4: fix setup_new_group_blocks locking Eric Sandeen
2007-10-01 19:24 ` [PATCH 2/2] - ext3: lighten up resize transaction requirements Eric Sandeen
2007-10-01 19:24 ` [PATCH 1/2] - ext3: fix setup_new_group_blocks locking Eric Sandeen
2007-10-02 5:42 ` Andreas Dilger
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).