From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
To: Solofo.Ramangalahy@bull.net
Cc: Jindrich Makovicka <makovick@gmail.com>, linux-ext4@vger.kernel.org
Subject: Re: data corruption with ext4 (from 2.6.27.4) exposed by rtorrent
Date: Thu, 6 Nov 2008 19:29:54 +0530 [thread overview]
Message-ID: <20081106135954.GD25194@skywalker> (raw)
In-Reply-To: <18705.63392.489856.682976@frecb006361.adech.frec.bull.fr>
On Wed, Nov 05, 2008 at 08:44:32PM +0100, Solofo.Ramangalahy@bull.net wrote:
> Hi Jindrich,
>
> Jindrich Makovicka writes:
> > The following testcase was used to trigger the infamous MAP_SHARED
> > dirty flag bug. Maybe it could be of some help here too:
> >
> > http://lkml.org/lkml/2006/12/27/180
>
> Thanks for remembering!
>
> The test case triggers corruption with 2.6.28-rc3 + ext4 patch queue:
> . bunch of errors like
> Chunk 71637 corrupted (0-1339) (2756-4095)
> Expected 213, got 0
> with default mount.
> . nodelalloc is ok.
I think below patch is needed. But even with the patch I am hitting the
corruption. So patch doesn't solve the problem. The change from tag
dirty lookup to index lookup should not have much impact because we are
writing from first_page to next_page - 1 contiguous page which should be
marked dirty anyway because we did a tag dirty lookup in
write_cache_pages and we did a lock page there.
commit 714736001d68cff26258bb80891c566a65a682c2
Author: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Date: Thu Nov 6 09:01:21 2008 +0530
ext4: Fix the delalloc writepages to allocate blocks at the right offset.
When iterating through the pages with all mapped buffer_heads
we failed to update the b_state value. This result in allocating
blocks at logical offset 0.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 7d2d2ea..2808984 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1667,35 +1667,41 @@ static void ext4_da_page_release_reservation(struct page *page,
*/
static int mpage_da_submit_io(struct mpage_da_data *mpd)
{
- struct address_space *mapping = mpd->inode->i_mapping;
- int ret = 0, err, nr_pages, i;
- unsigned long index, end;
- struct pagevec pvec;
long pages_skipped;
+ struct pagevec pvec;
+ unsigned long index, end;
+ int ret = 0, err, nr_pages, i;
+ struct inode *inode = mpd->inode;
+ struct buffer_head *lbh = &mpd->lbh;
+ struct address_space *mapping = inode->i_mapping;
BUG_ON(mpd->next_page <= mpd->first_page);
- pagevec_init(&pvec, 0);
+ /*
+ * we need to start from the first_page to the next_page - 1
+ * That is to make sure we also write the mapped dirty
+ * buffer_heads. If we look at mpd->lbh.b_blocknr we
+ * would only be looking at currently mapped buffer_heads.
+ */
index = mpd->first_page;
end = mpd->next_page - 1;
+ pagevec_init(&pvec, 0);
while (index <= end) {
- /*
- * We can use PAGECACHE_TAG_DIRTY lookup here because
- * even though we have cleared the dirty flag on the page
- * We still keep the page in the radix tree with tag
- * PAGECACHE_TAG_DIRTY. See clear_page_dirty_for_io.
- * The PAGECACHE_TAG_DIRTY is cleared in set_page_writeback
- * which is called via the below writepage callback.
- */
- nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
- PAGECACHE_TAG_DIRTY,
- min(end - index,
- (pgoff_t)PAGEVEC_SIZE-1) + 1);
+ nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE);
if (nr_pages == 0)
break;
for (i = 0; i < nr_pages; i++) {
struct page *page = pvec.pages[i];
+ index = page->index;
+ if (index > end)
+ break;
+ index++;
+
+ BUG_ON(!PageLocked(page));
+ BUG_ON(PageWriteback(page));
+ BUG_ON(!page_has_buffers(page));
+
pages_skipped = mpd->wbc->pages_skipped;
err = mapping->a_ops->writepage(page, mpd->wbc);
if (!err && (pages_skipped == mpd->wbc->pages_skipped))
@@ -2109,11 +2115,29 @@ static int __mpage_da_writepage(struct page *page,
bh = head;
do {
BUG_ON(buffer_locked(bh));
+ /*
+ * We need to try to allocte
+ * unmapped blocks in the same page.
+ * Otherwise we won't make progress
+ * with the page in ext4_da_writepage
+ */
if (buffer_dirty(bh) &&
(!buffer_mapped(bh) || buffer_delay(bh))) {
mpage_add_bh_to_extent(mpd, logical, bh);
if (mpd->io_done)
return MPAGE_DA_EXTENT_TAIL;
+ } else if (buffer_dirty(bh) && (buffer_mapped(bh))) {
+ /*
+ * mapped dirty buffer. We need to update
+ * the b_state because we look at
+ * b_state in mpage_da_map_blocks. We don't
+ * update b_size because if we find an
+ * unmapped buffer_head later we need to
+ * use the b_state flag of that buffer_head.
+ */
+ if (mpd->lbh.b_size == 0)
+ mpd->lbh.b_state =
+ bh->b_state & BH_FLAGS;
}
logical++;
} while ((bh = bh->b_this_page) != head);
next prev parent reply other threads:[~2008-11-06 14:00 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-03 12:42 data corruption with ext4 (from 2.6.27.4) exposed by rtorrent Roc Valles
2008-11-03 13:40 ` Theodore Tso
2008-11-03 13:47 ` Cryptooctoploid
2008-11-03 14:09 ` Roc Valles
2008-11-03 15:34 ` Cryptooctoploid
2008-11-03 15:51 ` Jindrich Makovicka
2008-11-05 19:44 ` Solofo.Ramangalahy
2008-11-05 19:57 ` Theodore Tso
2008-11-05 20:09 ` Solofo.Ramangalahy
2008-11-05 20:21 ` Solofo.Ramangalahy
2008-11-05 20:42 ` Theodore Tso
2008-11-05 20:52 ` Solofo.Ramangalahy
2008-11-06 10:15 ` Aneesh Kumar K.V
2008-11-06 10:36 ` Solofo.Ramangalahy
2008-11-06 13:47 ` Solofo.Ramangalahy
2008-11-06 13:59 ` Aneesh Kumar K.V [this message]
2008-11-05 13:34 ` Cryptooctoploid
2008-11-05 16:16 ` Eric Sandeen
2008-11-05 17:25 ` Theodore Tso
2008-11-05 20:13 ` Cryptooctoploid
2008-11-06 9:00 ` Roc Valles
2008-11-06 9:31 ` Cryptooctoploid
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=20081106135954.GD25194@skywalker \
--to=aneesh.kumar@linux.vnet.ibm.com \
--cc=Solofo.Ramangalahy@bull.net \
--cc=linux-ext4@vger.kernel.org \
--cc=makovick@gmail.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.