diff mbox

ext4: calculate journal credits correctly

Message ID 1226001075-16457-1-git-send-email-tytso@mit.edu
State Accepted, archived
Headers show

Commit Message

Theodore Ts'o Nov. 6, 2008, 7:51 p.m. UTC
This fixes a 2.6.27 regression which was introduced in commit a02908f1.

We weren't passing the chunk parameter down to the two subections,
ext4_indirect_trans_blocks() and ext4_ext_index_trans_blocks(), with
the result that massively overestimate the amount of credits needed by
ext4_da_writepages, especially in the non-extents case.  This causes
failures especially on /boot partitions, which tend to be small and
non-extent using since GRUB doesn't handle extents.

Thanks to Joseph Fannin for reporting this bug.

Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
 fs/ext4/inode.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

Comments

Mingming Cao Nov. 13, 2008, 12:03 a.m. UTC | #1
在 2008-11-06四的 14:51 -0500,Theodore Ts'o写道:
> This fixes a 2.6.27 regression which was introduced in commit a02908f1.
> 
> We weren't passing the chunk parameter down to the two subections,
> ext4_indirect_trans_blocks() and ext4_ext_index_trans_blocks(), with
> the result that massively overestimate the amount of credits needed by
> ext4_da_writepages, especially in the non-extents case.  This causes
> failures especially on /boot partitions, which tend to be small and
> non-extent using since GRUB doesn't handle extents.
> 
> Thanks to Joseph Fannin for reporting this bug.
> 
Thanks for fixing this up!

However, looking at the code path, I wasn't sure if we got the delalloc
credits right.  In ext4_da_writepages()->mpage_da_writepages(),  the
credits is calculated based on the assumption that mpage_da_writepages()
doing* one* single chunk of contigugous allocation? So only one single
extent credit is reserved (here you see the "chunk" flag passed from the
ext4_da_writepages)

__mpage_da_writepage() does do single chunk of block allocation at a
time, but mpage_da_writepages()->write_cache_pages() will loop the page
vectors and probably will calling writepage->__mpage_da_writepage->
mpage_da_map_blocks() multiple times?  Am I  missing anything?


> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
> ---
>  fs/ext4/inode.c |    5 +++--
>  1 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> index 8dbf695..5a130b5 100644
> --- a/fs/ext4/inode.c
> +++ b/fs/ext4/inode.c
> @@ -4580,9 +4580,10 @@ static int ext4_indirect_trans_blocks(struct inode *inode, int nrblocks,
>  static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
>  {
>  	if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
> -		return ext4_indirect_trans_blocks(inode, nrblocks, 0);
> -	return ext4_ext_index_trans_blocks(inode, nrblocks, 0);
> +		return ext4_indirect_trans_blocks(inode, nrblocks, chunk);
> +	return ext4_ext_index_trans_blocks(inode, nrblocks, chunk);
>  }
> +
>  /*
>   * Account for index blocks, block groups bitmaps and block group
>   * descriptor blocks if modify datablocks and index blocks

--
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
Aneesh Kumar K.V Nov. 23, 2008, 2:32 p.m. UTC | #2
On Wed, Nov 12, 2008 at 04:03:42PM -0800, Mingming Cao wrote:
> 
> 在 2008-11-06四的 14:51 -0500,Theodore Ts'o写道:
> > This fixes a 2.6.27 regression which was introduced in commit a02908f1.
> > 
> > We weren't passing the chunk parameter down to the two subections,
> > ext4_indirect_trans_blocks() and ext4_ext_index_trans_blocks(), with
> > the result that massively overestimate the amount of credits needed by
> > ext4_da_writepages, especially in the non-extents case.  This causes
> > failures especially on /boot partitions, which tend to be small and
> > non-extent using since GRUB doesn't handle extents.
> > 
> > Thanks to Joseph Fannin for reporting this bug.
> > 
> Thanks for fixing this up!

This was sent to my gmail.com  id so missed it before.
> 
> However, looking at the code path, I wasn't sure if we got the delalloc
> credits right.  In ext4_da_writepages()->mpage_da_writepages(),  the
> credits is calculated based on the assumption that mpage_da_writepages()
> doing* one* single chunk of contigugous allocation? So only one single
> extent credit is reserved (here you see the "chunk" flag passed from the
> ext4_da_writepages)
> 
> __mpage_da_writepage() does do single chunk of block allocation at a
> time, but mpage_da_writepages()->write_cache_pages() will loop the page
> vectors and probably will calling writepage->__mpage_da_writepage->
> mpage_da_map_blocks() multiple times?  Am I  missing anything?
> 

mpage_da_writepages does block allocation for single chunk only.
ext4_da_writepages allocate credit needed for single chunk allocation.
write_cache_pages iterate through contiguous pages and build an in
memory extent. It then call get_blocks for 'x' blocks. After that
we map the blocks to the unmapped buffer_heads. Then we do
ext4_da_writepage which redirty pages which are not fully mapped. That
means we skip pages. We retry using mpage_data_writepages again.

-aneesh
--
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
diff mbox

Patch

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 8dbf695..5a130b5 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -4580,9 +4580,10 @@  static int ext4_indirect_trans_blocks(struct inode *inode, int nrblocks,
 static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
 {
 	if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL))
-		return ext4_indirect_trans_blocks(inode, nrblocks, 0);
-	return ext4_ext_index_trans_blocks(inode, nrblocks, 0);
+		return ext4_indirect_trans_blocks(inode, nrblocks, chunk);
+	return ext4_ext_index_trans_blocks(inode, nrblocks, chunk);
 }
+
 /*
  * Account for index blocks, block groups bitmaps and block group
  * descriptor blocks if modify datablocks and index blocks