[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1300308774-14140-3-git-send-email-jack@suse.cz>
Date: Wed, 16 Mar 2011 21:52:54 +0100
From: Jan Kara <jack@...e.cz>
To: tytso@....edu
Cc: linux-ext4@...r.kernel.org, Jan Kara <jack@...e.cz>
Subject: [PATCH 2/2] ext4: Redirty page which could not be added to current extent in __mpage_da_writepage()
When a page cannot be added to current extent in __mpage_da_writepage() we
map current extent and send it for IO. Currently, mpage_da_submit_io() also
redirtied and unlocked this page but it's not clear whether this is just a
lucky accident or a well hidden intent. Actually, we get this wrong in the case
when ext4_map_blocks() fails because of EIO and thus mpage_da_submit_io()
doesn't get called and the page is left locked leading to deadlocks.
Fix the issue by explicitely redirtying and unlocking the page in
__mpage_da_writepage() whenever we see the page could not be added to the
current extent.
Signed-off-by: Jan Kara <jack@...e.cz>
---
fs/ext4/inode.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 337d9ca..aea9963 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -2465,6 +2465,7 @@ static int __mpage_da_writepage(struct page *page,
*/
if (mpd->next_page != mpd->first_page) {
mpage_da_map_and_submit(mpd);
+redirty_page:
/*
* skip rest of the page in the page_vec
*/
@@ -2477,6 +2478,7 @@ static int __mpage_da_writepage(struct page *page,
* Start next extent of pages ...
*/
mpd->first_page = page->index;
+ mpd->next_page = page->index + 1;
/*
* ... and blocks
@@ -2486,7 +2488,6 @@ static int __mpage_da_writepage(struct page *page,
mpd->b_blocknr = 0;
}
- mpd->next_page = page->index + 1;
logical = (sector_t) page->index <<
(PAGE_CACHE_SHIFT - inode->i_blkbits);
@@ -2494,7 +2495,7 @@ static int __mpage_da_writepage(struct page *page,
mpage_add_bh_to_extent(mpd, logical, PAGE_CACHE_SIZE,
(1 << BH_Dirty) | (1 << BH_Uptodate));
if (mpd->io_done)
- return MPAGE_DA_EXTENT_TAIL;
+ goto redirty_page;
} else {
/*
* Page with regular buffer heads, just add all dirty ones
@@ -2514,7 +2515,7 @@ static int __mpage_da_writepage(struct page *page,
bh->b_size,
bh->b_state);
if (mpd->io_done)
- return MPAGE_DA_EXTENT_TAIL;
+ goto redirty_page;
} else if (buffer_dirty(bh) && (buffer_mapped(bh))) {
/*
* mapped dirty buffer. We need to update
@@ -2530,6 +2531,7 @@ static int __mpage_da_writepage(struct page *page,
logical++;
} while ((bh = bh->b_this_page) != head);
}
+ mpd->next_page = page->index + 1;
return 0;
}
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists