aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJaegeuk Kim <jaegeuk@kernel.org>2016-01-07 16:23:12 -0500
committerJaegeuk Kim <jaegeuk@kernel.org>2016-01-08 14:45:22 -0500
commit12719ae14e57980ebf0a7baa63bc80494c76b192 (patch)
tree3eaf9696743ec4b17e35f79cb4c1f39db3f7b6a8
parent7612118ae8cdd36cbd74d873855d70252d2d49e3 (diff)
f2fs: avoid unnecessary f2fs_balance_fs calls
Only when node page is newly dirtied, it needs to check whether we need to do f2fs_gc. Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r--fs/f2fs/data.c4
-rw-r--r--fs/f2fs/f2fs.h4
-rw-r--r--fs/f2fs/inode.c19
-rw-r--r--fs/f2fs/node.c26
-rw-r--r--fs/f2fs/node.h4
-rw-r--r--fs/f2fs/super.c2
6 files changed, 30 insertions, 29 deletions
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 77c3bbb9bee0..3cf86fda8138 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -225,8 +225,8 @@ void set_data_blkaddr(struct dnode_of_data *dn)
225 /* Get physical address of data block */ 225 /* Get physical address of data block */
226 addr_array = blkaddr_in_node(rn); 226 addr_array = blkaddr_in_node(rn);
227 addr_array[ofs_in_node] = cpu_to_le32(dn->data_blkaddr); 227 addr_array[ofs_in_node] = cpu_to_le32(dn->data_blkaddr);
228 set_page_dirty(node_page); 228 if (set_page_dirty(node_page))
229 dn->node_changed = true; 229 dn->node_changed = true;
230} 230}
231 231
232int reserve_new_block(struct dnode_of_data *dn) 232int reserve_new_block(struct dnode_of_data *dn)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 882babaa678e..461b32923c14 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1674,8 +1674,8 @@ long f2fs_compat_ioctl(struct file *, unsigned int, unsigned long);
1674void f2fs_set_inode_flags(struct inode *); 1674void f2fs_set_inode_flags(struct inode *);
1675struct inode *f2fs_iget(struct super_block *, unsigned long); 1675struct inode *f2fs_iget(struct super_block *, unsigned long);
1676int try_to_free_nats(struct f2fs_sb_info *, int); 1676int try_to_free_nats(struct f2fs_sb_info *, int);
1677void update_inode(struct inode *, struct page *); 1677int update_inode(struct inode *, struct page *);
1678void update_inode_page(struct inode *); 1678int update_inode_page(struct inode *);
1679int f2fs_write_inode(struct inode *, struct writeback_control *); 1679int f2fs_write_inode(struct inode *, struct writeback_control *);
1680void f2fs_evict_inode(struct inode *); 1680void f2fs_evict_inode(struct inode *);
1681void handle_failed_inode(struct inode *); 1681void handle_failed_inode(struct inode *);
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index e95500802daa..cabc1ff108a1 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -222,7 +222,7 @@ bad_inode:
222 return ERR_PTR(ret); 222 return ERR_PTR(ret);
223} 223}
224 224
225void update_inode(struct inode *inode, struct page *node_page) 225int update_inode(struct inode *inode, struct page *node_page)
226{ 226{
227 struct f2fs_inode *ri; 227 struct f2fs_inode *ri;
228 228
@@ -260,15 +260,16 @@ void update_inode(struct inode *inode, struct page *node_page)
260 260
261 __set_inode_rdev(inode, ri); 261 __set_inode_rdev(inode, ri);
262 set_cold_node(inode, node_page); 262 set_cold_node(inode, node_page);
263 set_page_dirty(node_page);
264
265 clear_inode_flag(F2FS_I(inode), FI_DIRTY_INODE); 263 clear_inode_flag(F2FS_I(inode), FI_DIRTY_INODE);
264
265 return set_page_dirty(node_page);
266} 266}
267 267
268void update_inode_page(struct inode *inode) 268int update_inode_page(struct inode *inode)
269{ 269{
270 struct f2fs_sb_info *sbi = F2FS_I_SB(inode); 270 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
271 struct page *node_page; 271 struct page *node_page;
272 int ret = 0;
272retry: 273retry:
273 node_page = get_node_page(sbi, inode->i_ino); 274 node_page = get_node_page(sbi, inode->i_ino);
274 if (IS_ERR(node_page)) { 275 if (IS_ERR(node_page)) {
@@ -279,10 +280,11 @@ retry:
279 } else if (err != -ENOENT) { 280 } else if (err != -ENOENT) {
280 f2fs_stop_checkpoint(sbi); 281 f2fs_stop_checkpoint(sbi);
281 } 282 }
282 return; 283 return 0;
283 } 284 }
284 update_inode(inode, node_page); 285 ret = update_inode(inode, node_page);
285 f2fs_put_page(node_page, 1); 286 f2fs_put_page(node_page, 1);
287 return ret;
286} 288}
287 289
288int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) 290int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
@@ -300,9 +302,8 @@ int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc)
300 * We need to balance fs here to prevent from producing dirty node pages 302 * We need to balance fs here to prevent from producing dirty node pages
301 * during the urgent cleaning time when runing out of free sections. 303 * during the urgent cleaning time when runing out of free sections.
302 */ 304 */
303 update_inode_page(inode); 305 if (update_inode_page(inode))
304 306 f2fs_balance_fs(sbi);
305 f2fs_balance_fs(sbi);
306 return 0; 307 return 0;
307} 308}
308 309
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 5a2d800f4abc..c091b757bda6 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -543,7 +543,6 @@ int get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode)
543 543
544 set_nid(parent, offset[i - 1], nids[i], i == 1); 544 set_nid(parent, offset[i - 1], nids[i], i == 1);
545 alloc_nid_done(sbi, nids[i]); 545 alloc_nid_done(sbi, nids[i]);
546 dn->node_changed = true;
547 done = true; 546 done = true;
548 } else if (mode == LOOKUP_NODE_RA && i == level && level > 1) { 547 } else if (mode == LOOKUP_NODE_RA && i == level && level > 1) {
549 npage[i] = get_node_page_ra(parent, offset[i - 1]); 548 npage[i] = get_node_page_ra(parent, offset[i - 1]);
@@ -679,8 +678,8 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs,
679 ret = truncate_dnode(&rdn); 678 ret = truncate_dnode(&rdn);
680 if (ret < 0) 679 if (ret < 0)
681 goto out_err; 680 goto out_err;
682 set_nid(page, i, 0, false); 681 if (set_nid(page, i, 0, false))
683 dn->node_changed = true; 682 dn->node_changed = true;
684 } 683 }
685 } else { 684 } else {
686 child_nofs = nofs + ofs * (NIDS_PER_BLOCK + 1) + 1; 685 child_nofs = nofs + ofs * (NIDS_PER_BLOCK + 1) + 1;
@@ -693,8 +692,8 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs,
693 rdn.nid = child_nid; 692 rdn.nid = child_nid;
694 ret = truncate_nodes(&rdn, child_nofs, 0, depth - 1); 693 ret = truncate_nodes(&rdn, child_nofs, 0, depth - 1);
695 if (ret == (NIDS_PER_BLOCK + 1)) { 694 if (ret == (NIDS_PER_BLOCK + 1)) {
696 set_nid(page, i, 0, false); 695 if (set_nid(page, i, 0, false))
697 dn->node_changed = true; 696 dn->node_changed = true;
698 child_nofs += ret; 697 child_nofs += ret;
699 } else if (ret < 0 && ret != -ENOENT) { 698 } else if (ret < 0 && ret != -ENOENT) {
700 goto out_err; 699 goto out_err;
@@ -755,8 +754,8 @@ static int truncate_partial_nodes(struct dnode_of_data *dn,
755 err = truncate_dnode(dn); 754 err = truncate_dnode(dn);
756 if (err < 0) 755 if (err < 0)
757 goto fail; 756 goto fail;
758 set_nid(pages[idx], i, 0, false); 757 if (set_nid(pages[idx], i, 0, false))
759 dn->node_changed = true; 758 dn->node_changed = true;
760 } 759 }
761 760
762 if (offset[idx + 1] == 0) { 761 if (offset[idx + 1] == 0) {
@@ -981,7 +980,8 @@ struct page *new_node_page(struct dnode_of_data *dn,
981 fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true); 980 fill_node_footer(page, dn->nid, dn->inode->i_ino, ofs, true);
982 set_cold_node(dn->inode, page); 981 set_cold_node(dn->inode, page);
983 SetPageUptodate(page); 982 SetPageUptodate(page);
984 set_page_dirty(page); 983 if (set_page_dirty(page))
984 dn->node_changed = true;
985 985
986 if (f2fs_has_xattr_block(ofs)) 986 if (f2fs_has_xattr_block(ofs))
987 F2FS_I(dn->inode)->i_xattr_nid = dn->nid; 987 F2FS_I(dn->inode)->i_xattr_nid = dn->nid;
@@ -1138,18 +1138,20 @@ struct page *get_node_page_ra(struct page *parent, int start)
1138 1138
1139void sync_inode_page(struct dnode_of_data *dn) 1139void sync_inode_page(struct dnode_of_data *dn)
1140{ 1140{
1141 int ret = 0;
1142
1141 if (IS_INODE(dn->node_page) || dn->inode_page == dn->node_page) { 1143 if (IS_INODE(dn->node_page) || dn->inode_page == dn->node_page) {
1142 update_inode(dn->inode, dn->node_page); 1144 ret = update_inode(dn->inode, dn->node_page);
1143 } else if (dn->inode_page) { 1145 } else if (dn->inode_page) {
1144 if (!dn->inode_page_locked) 1146 if (!dn->inode_page_locked)
1145 lock_page(dn->inode_page); 1147 lock_page(dn->inode_page);
1146 update_inode(dn->inode, dn->inode_page); 1148 ret = update_inode(dn->inode, dn->inode_page);
1147 if (!dn->inode_page_locked) 1149 if (!dn->inode_page_locked)
1148 unlock_page(dn->inode_page); 1150 unlock_page(dn->inode_page);
1149 } else { 1151 } else {
1150 update_inode_page(dn->inode); 1152 ret = update_inode_page(dn->inode);
1151 } 1153 }
1152 dn->node_changed = true; 1154 dn->node_changed = ret ? true: false;
1153} 1155}
1154 1156
1155int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, 1157int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino,
diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
index 2de759a7746f..d4d1f636fe1c 100644
--- a/fs/f2fs/node.h
+++ b/fs/f2fs/node.h
@@ -317,7 +317,7 @@ static inline bool IS_DNODE(struct page *node_page)
317 return true; 317 return true;
318} 318}
319 319
320static inline void set_nid(struct page *p, int off, nid_t nid, bool i) 320static inline int set_nid(struct page *p, int off, nid_t nid, bool i)
321{ 321{
322 struct f2fs_node *rn = F2FS_NODE(p); 322 struct f2fs_node *rn = F2FS_NODE(p);
323 323
@@ -327,7 +327,7 @@ static inline void set_nid(struct page *p, int off, nid_t nid, bool i)
327 rn->i.i_nid[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid); 327 rn->i.i_nid[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid);
328 else 328 else
329 rn->in.nid[off] = cpu_to_le32(nid); 329 rn->in.nid[off] = cpu_to_le32(nid);
330 set_page_dirty(p); 330 return set_page_dirty(p);
331} 331}
332 332
333static inline nid_t get_nid(struct page *p, int off, bool i) 333static inline nid_t get_nid(struct page *p, int off, bool i)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 0bbd756821a7..f5cc790646e2 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -591,8 +591,6 @@ int f2fs_sync_fs(struct super_block *sb, int sync)
591 mutex_lock(&sbi->gc_mutex); 591 mutex_lock(&sbi->gc_mutex);
592 err = write_checkpoint(sbi, &cpc); 592 err = write_checkpoint(sbi, &cpc);
593 mutex_unlock(&sbi->gc_mutex); 593 mutex_unlock(&sbi->gc_mutex);
594 } else {
595 f2fs_balance_fs(sbi);
596 } 594 }
597 f2fs_trace_ios(NULL, 1); 595 f2fs_trace_ios(NULL, 1);
598 596