All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
To: Eric Sandeen <sandeen@redhat.com>
Cc: cmm@us.ibm.com, tytso@mit.edu, linux-ext4@vger.kernel.org
Subject: Re: [PATCH 2/3] ext4: Clear the unwritten buffer_head flag properly
Date: Fri, 8 May 2009 13:42:27 +0530	[thread overview]
Message-ID: <20090508081227.GA19157@skywalker> (raw)
In-Reply-To: <4A030011.7040901@redhat.com>

On Thu, May 07, 2009 at 10:36:49AM -0500, Eric Sandeen wrote:
> Aneesh Kumar K.V wrote:
> > ext4_get_blocks_wrap does a block lookup requesting to
> > allocate new blocks. A lookup of blocks in prealloc area
> > result in setting the unwritten flag in buffer_head. So
> > a write to an unwritten extent will cause the buffer_head
> > to have unwritten and mapped flag set. Clear hte unwritten
> > buffer_head flag before requesting to allocate blocks.
> > 
> > Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> > ---
> >  fs/ext4/inode.c |    7 +++++++
> >  1 files changed, 7 insertions(+), 0 deletions(-)
> > 
> > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
> > index c3cd00f..f6d7e9b 100644
> > --- a/fs/ext4/inode.c
> > +++ b/fs/ext4/inode.c
> > @@ -1149,6 +1149,7 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
> >  	int retval;
> >  
> >  	clear_buffer_mapped(bh);
> > +	clear_buffer_unwritten(bh);
> >  
> >  	/*
> >  	 * Try to see if we can get  the block without requesting
> > @@ -1179,6 +1180,12 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
> >  		return retval;
> >  
> >  	/*
> > +	 * The above get_blocks can cause the buffer to be
> > +	 * marked unwritten. So clear the same.
> > +	 */
> > +	clear_buffer_unwritten(bh);
> 
> hm, thinking out loud here.
> 
> ext4_ext_get_blocks() will only set unwritten if (!create) ... but then
> ext4_get_blocks_wrap() calls ext4_ext_get_blocks() !create as an
> argument no matter what, the first time, for an initial lookup.
> 
> But if ext4_get_blocks_wrap() was called with !create, then we return
> regardless, so ok - by the time you get to the above hunk, we -are- in
> create mode, we're planning to write it ... so I guess clearing the
> unwritten state makes sense here.
> 
> But is this too late, because it's after this?
> 
>         /*
>          * Returns if the blocks have already allocated
>          *
>          * Note that if blocks have been preallocated
>          * ext4_ext_get_block() returns th create = 0
>          * with buffer head unmapped.
>          */
>         if (retval > 0 && buffer_mapped(bh))
>                 return retval;
> 
> I guess not; ext4_ext_get_blocks() won't map the buffer if it's found to
> be preallocated/unwritten because it was called with !create.  If we're
> going on to write it, we want to clear unwritten.
> 
> So I guess this looks right, although I can't help but think that in
> general, the buffer_head state management is really getting to be a
> hard-to-follow mess...

To further clarify what i think was causing the I/O error.

1) We do a multi block delayed alloc to prealloc space. That would get
us multiple buffer_heads marked with BH_Unwritten. (say 10, 11, 12)
2) pdflush attempt to write some pages (say mapping block 10) which cause
a get_block call with create = 1. That would attempt to convert
uninitialized extent to initialized one. This can cause multiple blocks
to be marked initialized. ( say 10, 11 , 12)
3) We do an overwrite of block 11. That would mean we call
ext4_da_get_block_prep, which would again do a get_block for block 11
with create = 0. But remember we already have buffer_head marked with
BH_Unwritten flag. But the buffer was unmapped because it is unwritten
( We are fixing this mess in the patch for 2.6.31).
4) The get_block call will find the buffer mapped due to step b. And
mark the buffer_head mapped. There we go . We end up with buffer_head
mapped and unwritten
5) later in ext4_da_get_block_prep we check whether the buffer_head in marked
BH_Unwritten if so we set the block number to ~0. This is introduced by
[PATCH -V4 1/2] Fix sub-block zeroing for buffered writes into unwritten extents
6) So now we have a buffer_head that is mapped, unwritten, with
b_blocknr = ~0. That would result in the I/O error.

-aneesh



  reply	other threads:[~2009-05-08  8:13 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-07 10:39 [PATCH 1/3] ext4: Properly initialize the buffer_head state Aneesh Kumar K.V
2009-05-07 10:39 ` [PATCH 2/3] ext4: Clear the unwritten buffer_head flag properly Aneesh Kumar K.V
2009-05-07 10:39   ` [PATCH 3/3] vfs: Add BUG_ON for delayed and unwritten extents in submit_bh Aneesh Kumar K.V
2009-05-07 15:37     ` Eric Sandeen
2009-05-12  3:17     ` Theodore Tso
2009-05-12  4:52       ` [PATCH 3/3] vfs: Add BUG_ON for delayed and unwritten extentsin submit_bh Aneesh Kumar K.V
2009-05-12 13:25         ` Eric Sandeen
2009-05-07 15:36   ` [PATCH 2/3] ext4: Clear the unwritten buffer_head flag properly Eric Sandeen
2009-05-08  8:12     ` Aneesh Kumar K.V [this message]
2009-05-12  3:08   ` Theodore Tso
2009-05-12  4:46     ` Aneesh Kumar K.V
2009-05-13 18:56       ` Eric Sandeen
2009-05-13 22:28         ` Theodore Tso
2009-05-14  6:00           ` Aneesh Kumar K.V
2009-05-14  5:40         ` Aneesh Kumar K.V
2009-05-14 13:14           ` Theodore Tso
2009-05-07 15:20 ` [PATCH 1/3] ext4: Properly initialize the buffer_head state Eric Sandeen
2009-05-10 23:57   ` Theodore Tso
2009-05-11  9:24     ` Aneesh Kumar K.V
2009-05-11 11:31       ` Theodore Tso
2009-05-11 14:49     ` Eric Sandeen
2009-05-12  3:17 ` Theodore Tso
2009-05-12  4:47   ` Aneesh Kumar K.V

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090508081227.GA19157@skywalker \
    --to=aneesh.kumar@linux.vnet.ibm.com \
    --cc=cmm@us.ibm.com \
    --cc=linux-ext4@vger.kernel.org \
    --cc=sandeen@redhat.com \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is 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.