f2fs: split grab_cache_page and wait_on_page_writeback for node pages
authorJaegeuk Kim <jaegeuk.kim@samsung.com>
Tue, 29 Apr 2014 08:28:32 +0000 (17:28 +0900)
committerJaegeuk Kim <jaegeuk.kim@samsung.com>
Wed, 7 May 2014 01:21:58 +0000 (10:21 +0900)
This patch splits grab_cache_page_write_begin into grab_cache_page and
wait_on_page_writeback for node pages.

This patch intends to enhance the latency to get node pages by alleviating
unnecessary wait_on_page_writeback.

Signed-off-by: Chao Yu <chao2.yu@samsung.com>
Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
fs/f2fs/dir.c
fs/f2fs/inline.c
fs/f2fs/node.c
fs/f2fs/node.h
fs/f2fs/xattr.c

index 3581c2bde21b1f53ab2483b4df57c35ae6e88e19..c3f148555c378cf3942fa2860ffb8b04b7e542ef 100644 (file)
@@ -268,6 +268,8 @@ static void init_dent_inode(const struct qstr *name, struct page *ipage)
 {
        struct f2fs_inode *ri;
 
+       f2fs_wait_on_page_writeback(ipage, NODE);
+
        /* copy name info. to this inode page */
        ri = F2FS_INODE(ipage);
        ri->i_namelen = cpu_to_le32(name->len);
index d215dbb09f07dab9feba5d7a03479a9d01fb04b5..8bf34f052f67a40971aa907429c205b655307918 100644 (file)
@@ -156,6 +156,7 @@ int f2fs_write_inline_data(struct inode *inode,
                return err;
        ipage = dn.inode_page;
 
+       f2fs_wait_on_page_writeback(ipage, NODE);
        zero_user_segment(ipage, INLINE_DATA_OFFSET,
                                 INLINE_DATA_OFFSET + MAX_INLINE_DATA);
        src_addr = kmap(page);
@@ -188,6 +189,8 @@ void truncate_inline_data(struct inode *inode, u64 from)
        if (IS_ERR(ipage))
                return;
 
+       f2fs_wait_on_page_writeback(ipage, NODE);
+
        zero_user_segment(ipage, INLINE_DATA_OFFSET + from,
                                INLINE_DATA_OFFSET + MAX_INLINE_DATA);
        set_page_dirty(ipage);
@@ -218,6 +221,8 @@ process_inline:
                ipage = get_node_page(sbi, inode->i_ino);
                f2fs_bug_on(IS_ERR(ipage));
 
+               f2fs_wait_on_page_writeback(ipage, NODE);
+
                src_addr = inline_data_addr(npage);
                dst_addr = inline_data_addr(ipage);
                memcpy(dst_addr, src_addr, MAX_INLINE_DATA);
@@ -229,6 +234,7 @@ process_inline:
        if (f2fs_has_inline_data(inode)) {
                ipage = get_node_page(sbi, inode->i_ino);
                f2fs_bug_on(IS_ERR(ipage));
+               f2fs_wait_on_page_writeback(ipage, NODE);
                zero_user_segment(ipage, INLINE_DATA_OFFSET,
                                 INLINE_DATA_OFFSET + MAX_INLINE_DATA);
                clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
index 2803ef6cf53397f9b8c293cf0d7eceaff41a599c..059aaf5dda2b3173480de3f4687f2b9584b52980 100644 (file)
@@ -853,8 +853,7 @@ struct page *new_node_page(struct dnode_of_data *dn,
        if (unlikely(is_inode_flag_set(F2FS_I(dn->inode), FI_NO_ALLOC)))
                return ERR_PTR(-EPERM);
 
-       page = grab_cache_page_write_begin(NODE_MAPPING(sbi),
-                                       dn->nid, AOP_FLAG_NOFS);
+       page = grab_cache_page(NODE_MAPPING(sbi), dn->nid);
        if (!page)
                return ERR_PTR(-ENOMEM);
 
@@ -871,6 +870,7 @@ struct page *new_node_page(struct dnode_of_data *dn,
        new_ni.ino = dn->inode->i_ino;
        set_node_addr(sbi, &new_ni, NEW_ADDR, false);
 
+       f2fs_wait_on_page_writeback(page, NODE);
        fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true);
        set_cold_node(dn->inode, page);
        SetPageUptodate(page);
@@ -950,8 +950,7 @@ struct page *get_node_page(struct f2fs_sb_info *sbi, pgoff_t nid)
        struct page *page;
        int err;
 repeat:
-       page = grab_cache_page_write_begin(NODE_MAPPING(sbi),
-                                       nid, AOP_FLAG_NOFS);
+       page = grab_cache_page(NODE_MAPPING(sbi), nid);
        if (!page)
                return ERR_PTR(-ENOMEM);
 
@@ -1562,6 +1561,7 @@ static void recover_inline_xattr(struct inode *inode, struct page *page)
        src_addr = inline_xattr_addr(page);
        inline_size = inline_xattr_size(inode);
 
+       f2fs_wait_on_page_writeback(ipage, NODE);
        memcpy(dst_addr, src_addr, inline_size);
 
        update_inode(inode, ipage);
index a076c88bdca59cb2f3a443a9cf25054f5050bd73..4ee29d506f8cb8e336ef1c21885f5846d6c98f14 100644 (file)
@@ -272,7 +272,7 @@ static inline void set_nid(struct page *p, int off, nid_t nid, bool i)
 {
        struct f2fs_node *rn = F2FS_NODE(p);
 
-       wait_on_page_writeback(p);
+       f2fs_wait_on_page_writeback(p, NODE);
 
        if (i)
                rn->i.i_nid[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid);
index 6073f9f884162d225fe0fe1e8a2e8cf0a2dbc4b5..1f546b4b6b61913691d34ca11eaa8f61205fb5d5 100644 (file)
@@ -349,6 +349,7 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize,
 
                if (ipage) {
                        inline_addr = inline_xattr_addr(ipage);
+                       f2fs_wait_on_page_writeback(ipage, NODE);
                } else {
                        page = get_node_page(sbi, inode->i_ino);
                        if (IS_ERR(page)) {
@@ -356,6 +357,7 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize,
                                return PTR_ERR(page);
                        }
                        inline_addr = inline_xattr_addr(page);
+                       f2fs_wait_on_page_writeback(page, NODE);
                }
                memcpy(inline_addr, txattr_addr, inline_size);
                f2fs_put_page(page, 1);
@@ -376,6 +378,7 @@ static inline int write_all_xattrs(struct inode *inode, __u32 hsize,
                        return PTR_ERR(xpage);
                }
                f2fs_bug_on(new_nid);
+               f2fs_wait_on_page_writeback(xpage, NODE);
        } else {
                struct dnode_of_data dn;
                set_new_dnode(&dn, inode, NULL, NULL, new_nid);