aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/checkpoint.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-08 18:11:48 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-08 18:11:48 -0400
commit942d33da999b86821c9aee9615fcb81207ee04c7 (patch)
treedb14ab92982f936c0a2ea2202f5e301310f33bdd /fs/f2fs/checkpoint.c
parent246e6a0d781091c4657890ffa497c2576bd99095 (diff)
parent59bbd474abb9dd6a0c1a74df758ec29c7a8b150f (diff)
Merge tag 'f2fs-for-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs
Pull f2fs updates from Jaegeuk Kim: "This patch-set includes the following major enhancement patches. - introduce a new gloabl lock scheme - add tracepoints on several major functions - fix the overall cleaning process focused on victim selection - apply the block plugging to merge IOs as much as possible - enhance management of free nids and its list - enhance the readahead mode for node pages - address several cretical deadlock conditions - reduce lock_page calls The other minor bug fixes and enhancements are as follows. - calculation mistakes: overflow - bio types: READ, READA, and READ_SYNC - fix the recovery flow, data races, and null pointer errors" * tag 'f2fs-for-v3.10' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (68 commits) f2fs: cover free_nid management with spin_lock f2fs: optimize scan_nat_page() f2fs: code cleanup for scan_nat_page() and build_free_nids() f2fs: bugfix for alloc_nid_failed() f2fs: recover when journal contains deleted files f2fs: continue to mount after failing recovery f2fs: avoid deadlock during evict after f2fs_gc f2fs: modify the number of issued pages to merge IOs f2fs: remove useless #include <linux/proc_fs.h> as we're now using sysfs as debug entry. f2fs: fix inconsistent using of NM_WOUT_THRESHOLD f2fs: check truncation of mapping after lock_page f2fs: enhance alloc_nid and build_free_nids flows f2fs: add a tracepoint on f2fs_new_inode f2fs: check nid == 0 in add_free_nid f2fs: add REQ_META about metadata requests for submit f2fs: give a chance to merge IOs by IO scheduler f2fs: avoid frequent background GC f2fs: add tracepoints to debug checkpoint request f2fs: add tracepoints for write page operations f2fs: add tracepoints to debug the block allocation ...
Diffstat (limited to 'fs/f2fs/checkpoint.c')
-rw-r--r--fs/f2fs/checkpoint.c63
1 files changed, 32 insertions, 31 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 2b6fc131e2ce..b1de01da1a40 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -20,6 +20,7 @@
20#include "f2fs.h" 20#include "f2fs.h"
21#include "node.h" 21#include "node.h"
22#include "segment.h" 22#include "segment.h"
23#include <trace/events/f2fs.h>
23 24
24static struct kmem_cache *orphan_entry_slab; 25static struct kmem_cache *orphan_entry_slab;
25static struct kmem_cache *inode_entry_slab; 26static struct kmem_cache *inode_entry_slab;
@@ -57,13 +58,19 @@ repeat:
57 cond_resched(); 58 cond_resched();
58 goto repeat; 59 goto repeat;
59 } 60 }
60 if (f2fs_readpage(sbi, page, index, READ_SYNC)) { 61 if (PageUptodate(page))
62 goto out;
63
64 if (f2fs_readpage(sbi, page, index, READ_SYNC))
65 goto repeat;
66
67 lock_page(page);
68 if (page->mapping != mapping) {
61 f2fs_put_page(page, 1); 69 f2fs_put_page(page, 1);
62 goto repeat; 70 goto repeat;
63 } 71 }
72out:
64 mark_page_accessed(page); 73 mark_page_accessed(page);
65
66 /* We do not allow returning an errorneous page */
67 return page; 74 return page;
68} 75}
69 76
@@ -541,54 +548,44 @@ retry:
541 */ 548 */
542static void block_operations(struct f2fs_sb_info *sbi) 549static void block_operations(struct f2fs_sb_info *sbi)
543{ 550{
544 int t;
545 struct writeback_control wbc = { 551 struct writeback_control wbc = {
546 .sync_mode = WB_SYNC_ALL, 552 .sync_mode = WB_SYNC_ALL,
547 .nr_to_write = LONG_MAX, 553 .nr_to_write = LONG_MAX,
548 .for_reclaim = 0, 554 .for_reclaim = 0,
549 }; 555 };
556 struct blk_plug plug;
550 557
551 /* Stop renaming operation */ 558 blk_start_plug(&plug);
552 mutex_lock_op(sbi, RENAME);
553 mutex_lock_op(sbi, DENTRY_OPS);
554 559
555retry_dents: 560retry_flush_dents:
556 /* write all the dirty dentry pages */ 561 mutex_lock_all(sbi);
557 sync_dirty_dir_inodes(sbi);
558 562
559 mutex_lock_op(sbi, DATA_WRITE); 563 /* write all the dirty dentry pages */
560 if (get_pages(sbi, F2FS_DIRTY_DENTS)) { 564 if (get_pages(sbi, F2FS_DIRTY_DENTS)) {
561 mutex_unlock_op(sbi, DATA_WRITE); 565 mutex_unlock_all(sbi);
562 goto retry_dents; 566 sync_dirty_dir_inodes(sbi);
567 goto retry_flush_dents;
563 } 568 }
564 569
565 /* block all the operations */
566 for (t = DATA_NEW; t <= NODE_TRUNC; t++)
567 mutex_lock_op(sbi, t);
568
569 mutex_lock(&sbi->write_inode);
570
571 /* 570 /*
572 * POR: we should ensure that there is no dirty node pages 571 * POR: we should ensure that there is no dirty node pages
573 * until finishing nat/sit flush. 572 * until finishing nat/sit flush.
574 */ 573 */
575retry: 574retry_flush_nodes:
576 sync_node_pages(sbi, 0, &wbc); 575 mutex_lock(&sbi->node_write);
577
578 mutex_lock_op(sbi, NODE_WRITE);
579 576
580 if (get_pages(sbi, F2FS_DIRTY_NODES)) { 577 if (get_pages(sbi, F2FS_DIRTY_NODES)) {
581 mutex_unlock_op(sbi, NODE_WRITE); 578 mutex_unlock(&sbi->node_write);
582 goto retry; 579 sync_node_pages(sbi, 0, &wbc);
580 goto retry_flush_nodes;
583 } 581 }
584 mutex_unlock(&sbi->write_inode); 582 blk_finish_plug(&plug);
585} 583}
586 584
587static void unblock_operations(struct f2fs_sb_info *sbi) 585static void unblock_operations(struct f2fs_sb_info *sbi)
588{ 586{
589 int t; 587 mutex_unlock(&sbi->node_write);
590 for (t = NODE_WRITE; t >= RENAME; t--) 588 mutex_unlock_all(sbi);
591 mutex_unlock_op(sbi, t);
592} 589}
593 590
594static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) 591static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
@@ -727,9 +724,13 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
727 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); 724 struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi);
728 unsigned long long ckpt_ver; 725 unsigned long long ckpt_ver;
729 726
727 trace_f2fs_write_checkpoint(sbi->sb, is_umount, "start block_ops");
728
730 mutex_lock(&sbi->cp_mutex); 729 mutex_lock(&sbi->cp_mutex);
731 block_operations(sbi); 730 block_operations(sbi);
732 731
732 trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish block_ops");
733
733 f2fs_submit_bio(sbi, DATA, true); 734 f2fs_submit_bio(sbi, DATA, true);
734 f2fs_submit_bio(sbi, NODE, true); 735 f2fs_submit_bio(sbi, NODE, true);
735 f2fs_submit_bio(sbi, META, true); 736 f2fs_submit_bio(sbi, META, true);
@@ -746,13 +747,13 @@ void write_checkpoint(struct f2fs_sb_info *sbi, bool is_umount)
746 flush_nat_entries(sbi); 747 flush_nat_entries(sbi);
747 flush_sit_entries(sbi); 748 flush_sit_entries(sbi);
748 749
749 reset_victim_segmap(sbi);
750
751 /* unlock all the fs_lock[] in do_checkpoint() */ 750 /* unlock all the fs_lock[] in do_checkpoint() */
752 do_checkpoint(sbi, is_umount); 751 do_checkpoint(sbi, is_umount);
753 752
754 unblock_operations(sbi); 753 unblock_operations(sbi);
755 mutex_unlock(&sbi->cp_mutex); 754 mutex_unlock(&sbi->cp_mutex);
755
756 trace_f2fs_write_checkpoint(sbi->sb, is_umount, "finish checkpoint");
756} 757}
757 758
758void init_orphan_info(struct f2fs_sb_info *sbi) 759void init_orphan_info(struct f2fs_sb_info *sbi)