diff options
author | Jaegeuk Kim <jaegeuk@kernel.org> | 2016-01-07 16:23:12 -0500 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2016-01-08 14:45:22 -0500 |
commit | 12719ae14e57980ebf0a7baa63bc80494c76b192 (patch) | |
tree | 3eaf9696743ec4b17e35f79cb4c1f39db3f7b6a8 | |
parent | 7612118ae8cdd36cbd74d873855d70252d2d49e3 (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.c | 4 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 4 | ||||
-rw-r--r-- | fs/f2fs/inode.c | 19 | ||||
-rw-r--r-- | fs/f2fs/node.c | 26 | ||||
-rw-r--r-- | fs/f2fs/node.h | 4 | ||||
-rw-r--r-- | fs/f2fs/super.c | 2 |
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 | ||
232 | int reserve_new_block(struct dnode_of_data *dn) | 232 | int 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); | |||
1674 | void f2fs_set_inode_flags(struct inode *); | 1674 | void f2fs_set_inode_flags(struct inode *); |
1675 | struct inode *f2fs_iget(struct super_block *, unsigned long); | 1675 | struct inode *f2fs_iget(struct super_block *, unsigned long); |
1676 | int try_to_free_nats(struct f2fs_sb_info *, int); | 1676 | int try_to_free_nats(struct f2fs_sb_info *, int); |
1677 | void update_inode(struct inode *, struct page *); | 1677 | int update_inode(struct inode *, struct page *); |
1678 | void update_inode_page(struct inode *); | 1678 | int update_inode_page(struct inode *); |
1679 | int f2fs_write_inode(struct inode *, struct writeback_control *); | 1679 | int f2fs_write_inode(struct inode *, struct writeback_control *); |
1680 | void f2fs_evict_inode(struct inode *); | 1680 | void f2fs_evict_inode(struct inode *); |
1681 | void handle_failed_inode(struct inode *); | 1681 | void 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 | ||
225 | void update_inode(struct inode *inode, struct page *node_page) | 225 | int 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 | ||
268 | void update_inode_page(struct inode *inode) | 268 | int 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; | ||
272 | retry: | 273 | retry: |
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 | ||
288 | int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc) | 290 | int 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 | ||
1139 | void sync_inode_page(struct dnode_of_data *dn) | 1139 | void 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 | ||
1155 | int sync_node_pages(struct f2fs_sb_info *sbi, nid_t ino, | 1157 | int 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 | ||
320 | static inline void set_nid(struct page *p, int off, nid_t nid, bool i) | 320 | static 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 | ||
333 | static inline nid_t get_nid(struct page *p, int off, bool i) | 333 | static 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 | ||