diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-08 18:11:48 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-08 18:11:48 -0400 |
commit | 942d33da999b86821c9aee9615fcb81207ee04c7 (patch) | |
tree | db14ab92982f936c0a2ea2202f5e301310f33bdd /fs/f2fs/checkpoint.c | |
parent | 246e6a0d781091c4657890ffa497c2576bd99095 (diff) | |
parent | 59bbd474abb9dd6a0c1a74df758ec29c7a8b150f (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.c | 63 |
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 | ||
24 | static struct kmem_cache *orphan_entry_slab; | 25 | static struct kmem_cache *orphan_entry_slab; |
25 | static struct kmem_cache *inode_entry_slab; | 26 | static 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 | } |
72 | out: | ||
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 | */ |
542 | static void block_operations(struct f2fs_sb_info *sbi) | 549 | static 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 | ||
555 | retry_dents: | 560 | retry_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 | */ |
575 | retry: | 574 | retry_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 | ||
587 | static void unblock_operations(struct f2fs_sb_info *sbi) | 585 | static 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 | ||
594 | static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) | 591 | static 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 | ||
758 | void init_orphan_info(struct f2fs_sb_info *sbi) | 759 | void init_orphan_info(struct f2fs_sb_info *sbi) |