From: Mingming Cao <cmm@us.ibm.com>
To: Dmitri Monakhov <dmonakhov@openvz.org>
Cc: Eric Sandeen <sandeen@redhat.com>,
Solofo.Ramangalahy@bull.net, linux-ext4@vger.kernel.org
Subject: Re: [2.6.25-rc5-ext4-36c86] attempt to access beyond end of device
Date: Thu, 20 Mar 2008 17:49:08 -0700 [thread overview]
Message-ID: <1206060548.3637.53.camel@localhost.localdomain> (raw)
In-Reply-To: <20080320081619.GB13928@dmon-lap.sw.ru>
On Thu, 2008-03-20 at 11:16 +0300, Dmitri Monakhov wrote:
> On 21:39 Wed 19 Mar , Eric Sandeen wrote:
> > Solofo.Ramangalahy@bull.net wrote:
> > > Hello,
> > >
> > > During stress testing (workload: racer from ltp + fio/iometer), here
> > > is an error I am encountering:
> > > 8<------------------------------------------------------------------------------
> > > kernel: WARNING: at fs/buffer.c:1680 __block_write_full_page+0xd4/0x2af()
> >
> > So this is WARN_ON(bh->b_size != blocksize);
> >
> > What is b_size in this case?
> FS block size, because this page pinned bh (it comes from page_buffers(page)), but
> not dummy bh which may comes from {write,read}pages or direct_IO.
> Page's bh i_size must always be equal to fs blocksize.
> This bh always constructed via following construction
> if (!page_has_buffers(page))
> create_empty_buffers(page, 1<<inode->i_blkbits, flags)
> So page's bh->b_size was inited with right value from very beginning, but
> apparently somewhere this size was changed
> I guess i've localized buggy place, at least it's looks strange.
> ext4_da_get_block_prep ()
> {
> ...
> BUG_ON(create == 0);
> BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize);
> ret = ext4_get_blocks_wrap(NULL, inode, iblock, 1, bh_result, 0, 0);
> #Here ext4_get_block_write called with max_blocks == 1 ^^^^^
> ...
> if (ret > 0) {
> bh_result->b_size = (ret << inode->i_blkbits);
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> ## I don't understand this place. I hoped what (ret <= max_blocks) must always
> ##be true true. But after I've add debug info printing I've got following result.
> ret = 0;
> }
> ...
> }
> Some times I've seen following ,message
> bh= {state=0,size=114688, blknr=18446744073709551615 dev=0000000000000000,count=0}, ret=28
> And because it was page-cache's bh later this result in WARNING.
I think the root cause is here, ext4_get_block_wrap() could returns
number of blocks greater than the caller is asking for, and set the
mapped/allocated bytes in the bh->b_size.
The problem is that the for buffered IO (without delaloc) get_block()
via ext4_get_block_wrap() at write_begin time makes sure the buffer is
mapped, so later at the writepage()->block_write_full_page() time, it
never hits the branch the WARN_ON(bh->b_size != blocksize) in
__block_write_full_page(), even if the b_size is previously changed to
greater than the blocksize, by ext4_get_block_wrap() at the write_begin
time.
This warning is only seen with delayed allocation because we did a
get_block() (via ext4_da_get_block_prep()) look up with 1 block at a
time, but the bh->b_size is storing the length of the whole extent,
since ext4_get_block_wrap() could returns number of blocks greater than
the caller is asking for.
static int __block_write_full_page(struct inode *inode, struct page *page,
get_block_t *get_block, struct writeback_control *wbc)
{
....
if (!buffer_mapped(bh) && buffer_dirty(bh)) {
WARN_ON(bh->b_size != blocksize);
err = get_block(inode, block, bh, 1);
if (err)
goto recover;
if (buffer_new(bh)) {
/* blockdev mappings never come here */
clear_buffer_new(bh);
unmap_underlying_metadata(bh->b_bdev,
bh->b_blocknr);
}
}
I think the fix probabaly should enforce
ext4_get_blocks_handle()/ext4_ext_get_block() never map/allocate the
number of blocks that more than what is asking for..
Mingming
> >
> > -Eric
> > --
> > 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
> --
> 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
prev parent reply other threads:[~2008-03-21 0:49 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-18 9:49 [2.6.25-rc5-ext4-36c86] attempt to access beyond end of device Solofo.Ramangalahy
2008-03-18 16:23 ` Dmitri Monakhov
2008-03-20 2:19 ` Eric Sandeen
2008-03-19 11:35 ` Andreas Dilger
2008-03-19 11:56 ` Solofo.Ramangalahy
2008-03-20 2:39 ` Eric Sandeen
2008-03-20 3:04 ` Solofo.Ramangalahy
2008-03-20 8:16 ` Dmitri Monakhov
2008-03-20 12:09 ` Aneesh Kumar K.V
2008-03-20 14:04 ` delayed allocation result in BUG at fs/buffer.c:2880! Dmitri Monakhov
[not found] ` <20080320151645.GA23301@skywalker>
[not found] ` <1206033709.3637.15.camel@localhost.localdomain>
2008-03-20 18:02 ` Aneesh Kumar K.V
2008-03-20 18:18 ` Mingming Cao
2008-03-21 0:49 ` Mingming Cao [this message]
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=1206060548.3637.53.camel@localhost.localdomain \
--to=cmm@us.ibm.com \
--cc=Solofo.Ramangalahy@bull.net \
--cc=dmonakhov@openvz.org \
--cc=linux-ext4@vger.kernel.org \
--cc=sandeen@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is 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.