aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/node.c
diff options
context:
space:
mode:
authorChao Yu <yuchao0@huawei.com>2017-02-08 04:39:45 -0500
committerJaegeuk Kim <jaegeuk@kernel.org>2017-02-23 13:10:52 -0500
commitd260081ccf37f57b74396ec48f415f27d1b01b13 (patch)
tree1e7cd5fcda412d400209c061340b938fd9d8e122 /fs/f2fs/node.c
parent2ad0ef846b38288103d8373d1196c465df2c4d7d (diff)
f2fs: change recovery policy of xattr node block
Currently, if we call fsync after updating the xattr date belongs to the file, f2fs needs to trigger checkpoint to keep xattr data consistent. But, this policy cause low performance as checkpoint will block most foreground operations and cause unneeded and unrelated IOs around checkpoint. This patch will reuse regular file recovery policy for xattr node block, so, we change to write xattr node block tagged with fsync flag to warm area instead of cold area, and during recovery, we search warm node chain for fsynced xattr block, and do the recovery. So, for below application IO pattern, performance can be improved obviously: - touch file - create/update/delete xattr entry in file - fsync file Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Diffstat (limited to 'fs/f2fs/node.c')
-rw-r--r--fs/f2fs/node.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 8203a2f8b350..f8fb25a27b46 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -971,9 +971,6 @@ int truncate_xattr_node(struct inode *inode, struct page *page)
971 971
972 f2fs_i_xnid_write(inode, 0); 972 f2fs_i_xnid_write(inode, 0);
973 973
974 /* need to do checkpoint during fsync */
975 F2FS_I(inode)->xattr_ver = cur_cp_version(F2FS_CKPT(sbi));
976
977 set_new_dnode(&dn, inode, page, npage, nid); 974 set_new_dnode(&dn, inode, page, npage, nid);
978 975
979 if (page) 976 if (page)
@@ -2054,18 +2051,18 @@ update_inode:
2054 f2fs_put_page(ipage, 1); 2051 f2fs_put_page(ipage, 1);
2055} 2052}
2056 2053
2057void recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr) 2054int recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr)
2058{ 2055{
2059 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 2056 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
2060 nid_t prev_xnid = F2FS_I(inode)->i_xattr_nid; 2057 nid_t prev_xnid = F2FS_I(inode)->i_xattr_nid;
2061 nid_t new_xnid = nid_of_node(page); 2058 nid_t new_xnid = nid_of_node(page);
2062 struct node_info ni; 2059 struct node_info ni;
2060 struct page *xpage;
2063 2061
2064 /* 1: invalidate the previous xattr nid */
2065 if (!prev_xnid) 2062 if (!prev_xnid)
2066 goto recover_xnid; 2063 goto recover_xnid;
2067 2064
2068 /* Deallocate node address */ 2065 /* 1: invalidate the previous xattr nid */
2069 get_node_info(sbi, prev_xnid, &ni); 2066 get_node_info(sbi, prev_xnid, &ni);
2070 f2fs_bug_on(sbi, ni.blk_addr == NULL_ADDR); 2067 f2fs_bug_on(sbi, ni.blk_addr == NULL_ADDR);
2071 invalidate_blocks(sbi, ni.blk_addr); 2068 invalidate_blocks(sbi, ni.blk_addr);
@@ -2073,19 +2070,27 @@ void recover_xattr_data(struct inode *inode, struct page *page, block_t blkaddr)
2073 set_node_addr(sbi, &ni, NULL_ADDR, false); 2070 set_node_addr(sbi, &ni, NULL_ADDR, false);
2074 2071
2075recover_xnid: 2072recover_xnid:
2076 /* 2: allocate new xattr nid */ 2073 /* 2: update xattr nid in inode */
2074 remove_free_nid(sbi, new_xnid);
2075 f2fs_i_xnid_write(inode, new_xnid);
2077 if (unlikely(!inc_valid_node_count(sbi, inode))) 2076 if (unlikely(!inc_valid_node_count(sbi, inode)))
2078 f2fs_bug_on(sbi, 1); 2077 f2fs_bug_on(sbi, 1);
2078 update_inode_page(inode);
2079
2080 /* 3: update and set xattr node page dirty */
2081 xpage = grab_cache_page(NODE_MAPPING(sbi), new_xnid);
2082 if (!xpage)
2083 return -ENOMEM;
2084
2085 memcpy(F2FS_NODE(xpage), F2FS_NODE(page), PAGE_SIZE);
2079 2086
2080 remove_free_nid(sbi, new_xnid);
2081 get_node_info(sbi, new_xnid, &ni); 2087 get_node_info(sbi, new_xnid, &ni);
2082 ni.ino = inode->i_ino; 2088 ni.ino = inode->i_ino;
2083 set_node_addr(sbi, &ni, NEW_ADDR, false); 2089 set_node_addr(sbi, &ni, NEW_ADDR, false);
2084 f2fs_i_xnid_write(inode, new_xnid); 2090 set_page_dirty(xpage);
2091 f2fs_put_page(xpage, 1);
2085 2092
2086 /* 3: update xattr blkaddr */ 2093 return 0;
2087 refresh_sit_entry(sbi, NEW_ADDR, blkaddr);
2088 set_node_addr(sbi, &ni, blkaddr, false);
2089} 2094}
2090 2095
2091int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page) 2096int recover_inode_page(struct f2fs_sb_info *sbi, struct page *page)