Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b230e6ca authored by Jaegeuk Kim's avatar Jaegeuk Kim
Browse files

f2fs: handle writepage correctly



Previously, f2fs_write_data_pages() calls __f2fs_writepage() which calls
f2fs_write_data_page().
If f2fs_write_data_page() returns AOP_WRITEPAGE_ACTIVATE, __f2fs_writepage()
calls mapping_set_error(). But, this should not happen at every time, since
sometimes f2fs_write_data_page() tries to skip writing pages without error.
For example, volatile_write() gives EIO all the time, as Shuoran Liu pointed
out.

Reported-by: default avatarShuoran Liu <liushuoran@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent eb4246dc
Loading
Loading
Loading
Loading
+14 −30
Original line number Diff line number Diff line
@@ -1241,20 +1241,18 @@ static int f2fs_write_data_page(struct page *page,
			available_free_memory(sbi, BASE_CHECK))))
		goto redirty_out;

	/* Dentry blocks are controlled by checkpoint */
	if (S_ISDIR(inode->i_mode)) {
		if (unlikely(f2fs_cp_error(sbi)))
			goto redirty_out;
		err = do_write_data_page(&fio);
		goto done;
	}

	/* we should bypass data pages to proceed the kworkder jobs */
	if (unlikely(f2fs_cp_error(sbi))) {
		SetPageError(page);
		goto out;
	}

	/* Dentry blocks are controlled by checkpoint */
	if (S_ISDIR(inode->i_mode)) {
		err = do_write_data_page(&fio);
		goto done;
	}

	if (!wbc->for_reclaim)
		need_balance_fs = true;
	else if (has_not_enough_free_secs(sbi, 0))
@@ -1294,16 +1292,8 @@ static int f2fs_write_data_page(struct page *page,

redirty_out:
	redirty_page_for_writepage(wbc, page);
	return AOP_WRITEPAGE_ACTIVATE;
}

static int __f2fs_writepage(struct page *page, struct writeback_control *wbc,
			void *data)
{
	struct address_space *mapping = data;
	int ret = mapping->a_ops->writepage(page, wbc);
	mapping_set_error(mapping, ret);
	return ret;
	unlock_page(page);
	return err;
}

/*
@@ -1312,8 +1302,7 @@ static int __f2fs_writepage(struct page *page, struct writeback_control *wbc,
 * warm/hot data page.
 */
static int f2fs_write_cache_pages(struct address_space *mapping,
			struct writeback_control *wbc, writepage_t writepage,
			void *data)
					struct writeback_control *wbc)
{
	int ret = 0;
	int done = 0;
@@ -1395,17 +1384,12 @@ static int f2fs_write_cache_pages(struct address_space *mapping,
			if (!clear_page_dirty_for_io(page))
				goto continue_unlock;

			ret = (*writepage)(page, wbc, data);
			ret = mapping->a_ops->writepage(page, wbc);
			if (unlikely(ret)) {
				if (ret == AOP_WRITEPAGE_ACTIVATE) {
					unlock_page(page);
					ret = 0;
				} else {
				done_index = page->index + 1;
				done = 1;
				break;
			}
			}

			if (--wbc->nr_to_write <= 0 &&
			    wbc->sync_mode == WB_SYNC_NONE) {
@@ -1459,7 +1443,7 @@ static int f2fs_write_data_pages(struct address_space *mapping,

	trace_f2fs_writepages(mapping->host, wbc, DATA);

	ret = f2fs_write_cache_pages(mapping, wbc, __f2fs_writepage, mapping);
	ret = f2fs_write_cache_pages(mapping, wbc);
	/*
	 * if some pages were truncated, we cannot guarantee its mapping->host
	 * to detect pending bios.