f2fs: lookup extent cache first under IPU scenario

If a page is cold, NOT atomit written and need_ipu now, there is
a high probability that IPU should be adapted. For IPU, we try to
check extent tree to get the block index first, instead of reading
the dnode page, where may lead to an useless dnode IO, since no need to
update the dnode index for IPU.

Signed-off-by: Hou Pengyang <houpengyang@huawei.com>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index dfc974c..ca21ecb 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1350,9 +1350,20 @@
 	struct page *page = fio->page;
 	struct inode *inode = page->mapping->host;
 	struct dnode_of_data dn;
+	struct extent_info ei = {0,0,0};
+	bool ipu_force = false;
 	int err = 0;
 
 	set_new_dnode(&dn, inode, NULL, NULL, 0);
+	if (need_inplace_update(fio) &&
+			f2fs_lookup_extent_cache(inode, page->index, &ei)) {
+		fio->old_blkaddr = ei.blk + page->index - ei.fofs;
+		if (fio->old_blkaddr != NULL_ADDR &&
+				fio->old_blkaddr != NEW_ADDR) {
+			ipu_force = true;
+			goto got_it;
+		}
+	}
 	err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
 	if (err)
 		return err;
@@ -1364,7 +1375,7 @@
 		ClearPageUptodate(page);
 		goto out_writepage;
 	}
-
+got_it:
 	err = encrypt_one_page(fio);
 	if (err)
 		goto out_writepage;
@@ -1375,7 +1386,7 @@
 	 * If current allocation needs SSR,
 	 * it had better in-place writes for updated data.
 	 */
-	if (need_inplace_update(fio)) {
+	if (ipu_force || need_inplace_update(fio)) {
 		f2fs_bug_on(fio->sbi, !fio->cp_rwsem_locked);
 		f2fs_unlock_op(fio->sbi);
 		fio->cp_rwsem_locked = false;
@@ -1412,6 +1423,7 @@
 		.type = DATA,
 		.op = REQ_OP_WRITE,
 		.op_flags = wbc_to_write_flags(wbc),
+		.old_blkaddr = NULL_ADDR,
 		.page = page,
 		.encrypted_page = NULL,
 		.submitted = false,
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 84db41c..c2a9ae8 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -714,6 +714,7 @@
 			.type = DATA,
 			.op = REQ_OP_WRITE,
 			.op_flags = REQ_SYNC,
+			.old_blkaddr = NULL_ADDR,
 			.page = page,
 			.encrypted_page = NULL,
 		};
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 35d5d49..38b97ad6 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -311,6 +311,7 @@
 			}
 
 			fio.page = page;
+			fio.old_blkaddr = NULL_ADDR;
 			err = do_write_data_page(&fio);
 			if (err) {
 				unlock_page(page);