diff options
| author | Andrew Morton <akpm@osdl.org> | 2005-05-05 19:16:02 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-05 19:36:44 -0400 |
| commit | d17d7fa44dbe1f12031773e27eda9e939024a037 (patch) | |
| tree | 4b2a8ebb60907a5cde4dd02b737851525a24a588 | |
| parent | ecffdde68ebefa1aa24411a91b12ae649f71f71c (diff) | |
[PATCH] revert ext3-writepages-support-for-writeback-mode
This had a fatal lock ranking bug: we do journal_start outside
mpage_writepages()'s lock_page().
Revert the whole thing, think again.
Credit-to: Jan Kara <jack@suse.cz>
For identifying the bug.
Cc: Badari Pulavarty <pbadari@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | fs/ext3/inode.c | 46 | ||||
| -rw-r--r-- | fs/mpage.c | 12 | ||||
| -rw-r--r-- | include/linux/mpage.h | 3 |
3 files changed, 1 insertions, 60 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index ea5888688f94..0d5fa73b18dc 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
| @@ -844,12 +844,6 @@ get_block: | |||
| 844 | return ret; | 844 | return ret; |
| 845 | } | 845 | } |
| 846 | 846 | ||
| 847 | static int ext3_writepages_get_block(struct inode *inode, sector_t iblock, | ||
| 848 | struct buffer_head *bh, int create) | ||
| 849 | { | ||
| 850 | return ext3_direct_io_get_blocks(inode, iblock, 1, bh, create); | ||
| 851 | } | ||
| 852 | |||
| 853 | /* | 847 | /* |
| 854 | * `handle' can be NULL if create is zero | 848 | * `handle' can be NULL if create is zero |
| 855 | */ | 849 | */ |
| @@ -1323,45 +1317,6 @@ out_fail: | |||
| 1323 | return ret; | 1317 | return ret; |
| 1324 | } | 1318 | } |
| 1325 | 1319 | ||
| 1326 | static int | ||
| 1327 | ext3_writeback_writepage_helper(struct page *page, | ||
| 1328 | struct writeback_control *wbc) | ||
| 1329 | { | ||
| 1330 | return block_write_full_page(page, ext3_get_block, wbc); | ||
| 1331 | } | ||
| 1332 | |||
| 1333 | static int | ||
| 1334 | ext3_writeback_writepages(struct address_space *mapping, | ||
| 1335 | struct writeback_control *wbc) | ||
| 1336 | { | ||
| 1337 | struct inode *inode = mapping->host; | ||
| 1338 | handle_t *handle = NULL; | ||
| 1339 | int err, ret = 0; | ||
| 1340 | |||
| 1341 | if (!mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) | ||
| 1342 | return ret; | ||
| 1343 | |||
| 1344 | handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); | ||
| 1345 | if (IS_ERR(handle)) { | ||
| 1346 | ret = PTR_ERR(handle); | ||
| 1347 | return ret; | ||
| 1348 | } | ||
| 1349 | |||
| 1350 | ret = __mpage_writepages(mapping, wbc, ext3_writepages_get_block, | ||
| 1351 | ext3_writeback_writepage_helper); | ||
| 1352 | |||
| 1353 | /* | ||
| 1354 | * Need to reaquire the handle since ext3_writepages_get_block() | ||
| 1355 | * can restart the handle | ||
| 1356 | */ | ||
| 1357 | handle = journal_current_handle(); | ||
| 1358 | |||
| 1359 | err = ext3_journal_stop(handle); | ||
| 1360 | if (!ret) | ||
| 1361 | ret = err; | ||
| 1362 | return ret; | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | static int ext3_writeback_writepage(struct page *page, | 1320 | static int ext3_writeback_writepage(struct page *page, |
| 1366 | struct writeback_control *wbc) | 1321 | struct writeback_control *wbc) |
| 1367 | { | 1322 | { |
| @@ -1599,7 +1554,6 @@ static struct address_space_operations ext3_writeback_aops = { | |||
| 1599 | .readpage = ext3_readpage, | 1554 | .readpage = ext3_readpage, |
| 1600 | .readpages = ext3_readpages, | 1555 | .readpages = ext3_readpages, |
| 1601 | .writepage = ext3_writeback_writepage, | 1556 | .writepage = ext3_writeback_writepage, |
| 1602 | .writepages = ext3_writeback_writepages, | ||
| 1603 | .sync_page = block_sync_page, | 1557 | .sync_page = block_sync_page, |
| 1604 | .prepare_write = ext3_prepare_write, | 1558 | .prepare_write = ext3_prepare_write, |
| 1605 | .commit_write = ext3_writeback_commit_write, | 1559 | .commit_write = ext3_writeback_commit_write, |
diff --git a/fs/mpage.c b/fs/mpage.c index 32c7c8fcfce7..68db5256a727 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
| @@ -627,15 +627,6 @@ int | |||
| 627 | mpage_writepages(struct address_space *mapping, | 627 | mpage_writepages(struct address_space *mapping, |
| 628 | struct writeback_control *wbc, get_block_t get_block) | 628 | struct writeback_control *wbc, get_block_t get_block) |
| 629 | { | 629 | { |
| 630 | return __mpage_writepages(mapping, wbc, get_block, | ||
| 631 | mapping->a_ops->writepage); | ||
| 632 | } | ||
| 633 | |||
| 634 | int | ||
| 635 | __mpage_writepages(struct address_space *mapping, | ||
| 636 | struct writeback_control *wbc, get_block_t get_block, | ||
| 637 | writepage_t writepage_fn) | ||
| 638 | { | ||
| 639 | struct backing_dev_info *bdi = mapping->backing_dev_info; | 630 | struct backing_dev_info *bdi = mapping->backing_dev_info; |
| 640 | struct bio *bio = NULL; | 631 | struct bio *bio = NULL; |
| 641 | sector_t last_block_in_bio = 0; | 632 | sector_t last_block_in_bio = 0; |
| @@ -725,7 +716,7 @@ retry: | |||
| 725 | } else { | 716 | } else { |
| 726 | bio = __mpage_writepage(bio, page, get_block, | 717 | bio = __mpage_writepage(bio, page, get_block, |
| 727 | &last_block_in_bio, &ret, wbc, | 718 | &last_block_in_bio, &ret, wbc, |
| 728 | writepage_fn); | 719 | page->mapping->a_ops->writepage); |
| 729 | } | 720 | } |
| 730 | if (unlikely(ret == WRITEPAGE_ACTIVATE)) | 721 | if (unlikely(ret == WRITEPAGE_ACTIVATE)) |
| 731 | unlock_page(page); | 722 | unlock_page(page); |
| @@ -755,7 +746,6 @@ retry: | |||
| 755 | return ret; | 746 | return ret; |
| 756 | } | 747 | } |
| 757 | EXPORT_SYMBOL(mpage_writepages); | 748 | EXPORT_SYMBOL(mpage_writepages); |
| 758 | EXPORT_SYMBOL(__mpage_writepages); | ||
| 759 | 749 | ||
| 760 | int mpage_writepage(struct page *page, get_block_t get_block, | 750 | int mpage_writepage(struct page *page, get_block_t get_block, |
| 761 | struct writeback_control *wbc) | 751 | struct writeback_control *wbc) |
diff --git a/include/linux/mpage.h b/include/linux/mpage.h index dea1b0083661..3ca880463c47 100644 --- a/include/linux/mpage.h +++ b/include/linux/mpage.h | |||
| @@ -20,9 +20,6 @@ int mpage_writepages(struct address_space *mapping, | |||
| 20 | struct writeback_control *wbc, get_block_t get_block); | 20 | struct writeback_control *wbc, get_block_t get_block); |
| 21 | int mpage_writepage(struct page *page, get_block_t *get_block, | 21 | int mpage_writepage(struct page *page, get_block_t *get_block, |
| 22 | struct writeback_control *wbc); | 22 | struct writeback_control *wbc); |
| 23 | int __mpage_writepages(struct address_space *mapping, | ||
| 24 | struct writeback_control *wbc, get_block_t get_block, | ||
| 25 | writepage_t writepage); | ||
| 26 | 23 | ||
| 27 | static inline int | 24 | static inline int |
| 28 | generic_writepages(struct address_space *mapping, struct writeback_control *wbc) | 25 | generic_writepages(struct address_space *mapping, struct writeback_control *wbc) |
