Commit d17d7fa4 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds
Browse files

[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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ecffdde6
Loading
Loading
Loading
Loading
+0 −46
Original line number Diff line number Diff line
@@ -844,12 +844,6 @@ get_block:
	return ret;
}

static int ext3_writepages_get_block(struct inode *inode, sector_t iblock,
			struct buffer_head *bh, int create)
{
	return ext3_direct_io_get_blocks(inode, iblock, 1, bh, create);
}

/*
 * `handle' can be NULL if create is zero
 */
@@ -1323,45 +1317,6 @@ out_fail:
	return ret;
}

static int
ext3_writeback_writepage_helper(struct page *page,
				struct writeback_control *wbc)
{
	return block_write_full_page(page, ext3_get_block, wbc);
}

static int
ext3_writeback_writepages(struct address_space *mapping,
				struct writeback_control *wbc)
{
	struct inode *inode = mapping->host;
	handle_t *handle = NULL;
	int err, ret = 0;

	if (!mapping_tagged(mapping, PAGECACHE_TAG_DIRTY))
		return ret;

	handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
	if (IS_ERR(handle)) {
		ret = PTR_ERR(handle);
		return ret;
	}

        ret = __mpage_writepages(mapping, wbc, ext3_writepages_get_block,
					ext3_writeback_writepage_helper);

	/*
	 * Need to reaquire the handle since ext3_writepages_get_block()
	 * can restart the handle
	 */
	handle = journal_current_handle();

	err = ext3_journal_stop(handle);
	if (!ret)
		ret = err;
	return ret;
}

static int ext3_writeback_writepage(struct page *page,
				struct writeback_control *wbc)
{
@@ -1599,7 +1554,6 @@ static struct address_space_operations ext3_writeback_aops = {
	.readpage	= ext3_readpage,
	.readpages	= ext3_readpages,
	.writepage	= ext3_writeback_writepage,
	.writepages	= ext3_writeback_writepages,
	.sync_page	= block_sync_page,
	.prepare_write	= ext3_prepare_write,
	.commit_write	= ext3_writeback_commit_write,
+1 −11
Original line number Diff line number Diff line
@@ -626,15 +626,6 @@ out:
int
mpage_writepages(struct address_space *mapping,
		struct writeback_control *wbc, get_block_t get_block)
{
	return __mpage_writepages(mapping, wbc, get_block,
		mapping->a_ops->writepage);
}

int
__mpage_writepages(struct address_space *mapping,
		struct writeback_control *wbc, get_block_t get_block,
		writepage_t writepage_fn)
{
	struct backing_dev_info *bdi = mapping->backing_dev_info;
	struct bio *bio = NULL;
@@ -725,7 +716,7 @@ retry:
			} else {
				bio = __mpage_writepage(bio, page, get_block,
						&last_block_in_bio, &ret, wbc,
						writepage_fn);
						page->mapping->a_ops->writepage);
			}
			if (unlikely(ret == WRITEPAGE_ACTIVATE))
				unlock_page(page);
@@ -755,7 +746,6 @@ retry:
	return ret;
}
EXPORT_SYMBOL(mpage_writepages);
EXPORT_SYMBOL(__mpage_writepages);

int mpage_writepage(struct page *page, get_block_t get_block,
	struct writeback_control *wbc)
+0 −3
Original line number Diff line number Diff line
@@ -20,9 +20,6 @@ int mpage_writepages(struct address_space *mapping,
		struct writeback_control *wbc, get_block_t get_block);
int mpage_writepage(struct page *page, get_block_t *get_block,
		struct writeback_control *wbc);
int __mpage_writepages(struct address_space *mapping,
		struct writeback_control *wbc, get_block_t get_block,
		writepage_t writepage);

static inline int
generic_writepages(struct address_space *mapping, struct writeback_control *wbc)