[f2fs-dev] [PATCH 2/3] f2fs: lookup extent cache first under IPU scenario

2017-04-22 Thread Hou Pengyang
Signed-off-by: Hou Pengyang 
Signed-off-by: Chao Yu 
---
 fs/f2fs/data.c | 24 
 1 file changed, 24 insertions(+)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 6b18750..1c99ae1 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1367,8 +1367,32 @@ int do_write_data_page(struct f2fs_io_info *fio)
struct page *page = fio->page;
struct inode *inode = page->mapping->host;
struct dnode_of_data dn;
+   struct extent_info ei = {0,0,0};
int err = 0;
 
+   /*
+* 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.
+*/
+   if (unlikely(need_inplace_update_block(fio, page) &&
+   f2fs_lookup_extent_cache(inode, page->index, &ei))) {
+
+   fio->old_blkaddr = ei.blk + page->index - ei.fofs;
+
+   if (fio->old_blkaddr != NEW_ADDR &&
+   fio->old_blkaddr != NULL_ADDR) {
+   err = f2fs_encrypt_page(fio, page);
+   if (err)
+   return err;
+   set_page_writeback(page);
+   err = do_rewrite_data_page(fio, page);
+   return err;
+   }
+   }
+
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
if (err)
-- 
2.10.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 1/3] f2fs: reconstruct code to write a data page

2017-04-22 Thread Hou Pengyang
This patch introduces two functions:

1) f2fs_encrypt_page -- encrypt data page before submit_bio
2) do_rewrite_data_page -- IPU rewrite

The two functions are extraced from do_write_data_page, logic in
do_write_data_page stays unchanged.

Signed-off-by: Hou Pengyang 
Signed-off-by: Chao Yu 
---
 fs/f2fs/data.c | 83 --
 1 file changed, 58 insertions(+), 25 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index b8dcd1e..6b18750 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1302,26 +1302,11 @@ static int f2fs_read_data_pages(struct file *file,
return f2fs_mpage_readpages(mapping, pages, NULL, nr_pages);
 }
 
-int do_write_data_page(struct f2fs_io_info *fio)
+static int f2fs_encrypt_page(struct f2fs_io_info *fio, struct page *page)
 {
-   struct page *page = fio->page;
struct inode *inode = page->mapping->host;
-   struct dnode_of_data dn;
int err = 0;
 
-   set_new_dnode(&dn, inode, NULL, NULL, 0);
-   err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
-   if (err)
-   return err;
-
-   fio->old_blkaddr = dn.data_blkaddr;
-
-   /* This page is already truncated */
-   if (fio->old_blkaddr == NULL_ADDR) {
-   ClearPageUptodate(page);
-   goto out_writepage;
-   }
-
if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) {
gfp_t gfp_flags = GFP_NOFS;
 
@@ -1343,9 +1328,63 @@ int do_write_data_page(struct f2fs_io_info *fio)
err = 0;
goto retry_encrypt;
}
-   goto out_writepage;
+   return err;
}
}
+   return err;
+}
+
+static int do_rewrite_data_page(struct f2fs_io_info *fio, struct page *page)
+{
+   struct inode *inode = page->mapping->host;
+   int err;
+
+   f2fs_bug_on(F2FS_P_SB(page), !fio->cp_rwsem_locked);
+
+   f2fs_unlock_op(F2FS_I_SB(inode));
+   fio->cp_rwsem_locked = false;
+   err = rewrite_data_page(fio);
+   set_inode_flag(inode, FI_UPDATE_WRITE);
+   trace_f2fs_do_write_data_page(page, IPU);
+   return err;
+
+}
+
+static inline bool need_inplace_update_block(struct f2fs_io_info *fio, struct 
page *page)
+{
+   struct inode *inode = page->mapping->host;
+
+   if (!is_cold_data(page) &&
+   !IS_ATOMIC_WRITTEN_PAGE(page) &&
+   need_inplace_update(inode, fio))
+   return true;
+
+   return false;
+}
+
+int do_write_data_page(struct f2fs_io_info *fio)
+{
+   struct page *page = fio->page;
+   struct inode *inode = page->mapping->host;
+   struct dnode_of_data dn;
+   int err = 0;
+
+   set_new_dnode(&dn, inode, NULL, NULL, 0);
+   err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
+   if (err)
+   return err;
+
+   fio->old_blkaddr = dn.data_blkaddr;
+
+   /* This page is already truncated */
+   if (fio->old_blkaddr == NULL_ADDR) {
+   ClearPageUptodate(page);
+   goto out_writepage;
+   }
+
+   err = f2fs_encrypt_page(fio, page);
+   if (err)
+   goto out_writepage;
 
set_page_writeback(page);
 
@@ -1354,14 +1393,8 @@ int do_write_data_page(struct f2fs_io_info *fio)
 * it had better in-place writes for updated data.
 */
if (unlikely(fio->old_blkaddr != NEW_ADDR &&
-   !is_cold_data(page) &&
-   !IS_ATOMIC_WRITTEN_PAGE(page) &&
-   need_inplace_update(inode, fio))) {
-   f2fs_unlock_op(F2FS_I_SB(inode));
-   fio->cp_rwsem_locked = false;
-   err = rewrite_data_page(fio);
-   set_inode_flag(inode, FI_UPDATE_WRITE);
-   trace_f2fs_do_write_data_page(page, IPU);
+   need_inplace_update_block(fio, page))) {
+   err = do_rewrite_data_page(fio, page);
} else {
write_data_page(&dn, fio);
trace_f2fs_do_write_data_page(page, OPU);
-- 
2.10.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 0/3] optimize f2fs IPU v2

2017-04-22 Thread Hou Pengyang
For IPU, there is no need to read dnode, these three patches are to fix this
issue.

patch 1): Reconstruct code in do_write_data_page, code logic stays unchanged,
patch 2): Under high-probability IPU scenario, we check extent_tree first
patch 3): Unlock dnode before IPU

v1->v2:
1) fix 
if(f2fs_encrypt_page())
XXX
to 
err = f2fs_encrypt_page() 
if (err)
XXX

otherwise do_write_data_page would return a wrong return value.

2) extract need_in_place_block(fio, page) for IPU checking.

Hou Pengyang (3):
  f2fs: reconstruct code to write a data page
  f2fs: lookup extent cache first under IPU scenario
  f2fs: unlock dnode before IPU

 fs/f2fs/data.c | 109 -
 1 file changed, 84 insertions(+), 25 deletions(-)

-- 
2.10.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH 3/3] f2fs: unlock dnode before IPU

2017-04-22 Thread Hou Pengyang
Signed-off-by: Hou Pengyang 
---
 fs/f2fs/data.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 1c99ae1..a0df451 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1418,7 +1418,9 @@ int do_write_data_page(struct f2fs_io_info *fio)
 */
if (unlikely(fio->old_blkaddr != NEW_ADDR &&
need_inplace_update_block(fio, page))) {
+   f2fs_put_dnode(&dn);
err = do_rewrite_data_page(fio, page);
+   return err;
} else {
write_data_page(&dn, fio);
trace_f2fs_do_write_data_page(page, OPU);
-- 
2.10.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel


[f2fs-dev] [PATCH] f2fs: seperate read nat page from nat_tree_lock

2017-04-22 Thread Yunlei He
This patch seperate nat page read io from nat_tree_lock.

-lock_page
-get_node_info()
-current_nat_addr

..  ->   write_checkpoint

-get_meta_page

Because we lock node page, we can make sure no other threads
modify this nid concurrently. So we just obtain current_nat_addr
under nat_tree_lock, node info is always same in both nat pack.

Signed-off-by: Yunlei He 
---
 fs/f2fs/node.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index ad54e90..b99e318 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -376,6 +376,7 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, 
struct node_info *ni)
struct page *page = NULL;
struct f2fs_nat_entry ne;
struct nat_entry *e;
+   pgoff_t index;
int i;
 
ni->nid = nid;
@@ -401,17 +402,21 @@ void get_node_info(struct f2fs_sb_info *sbi, nid_t nid, 
struct node_info *ni)
node_info_from_raw_nat(ni, &ne);
}
up_read(&curseg->journal_rwsem);
-   if (i >= 0)
+   if (i >= 0) {
+   up_read(&nm_i->nat_tree_lock);
goto cache;
+   }
 
/* Fill node_info from nat page */
-   page = get_current_nat_page(sbi, start_nid);
+   index = current_nat_addr(sbi, nid);
+   up_read(&nm_i->nat_tree_lock);
+
+   page = get_meta_page(sbi, index);
nat_blk = (struct f2fs_nat_block *)page_address(page);
ne = nat_blk->entries[nid - start_nid];
node_info_from_raw_nat(ni, &ne);
f2fs_put_page(page, 1);
 cache:
-   up_read(&nm_i->nat_tree_lock);
/* cache nat entry */
down_write(&nm_i->nat_tree_lock);
cache_nat_entry(sbi, nid, &ne);
-- 
2.10.1


--
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
___
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel