aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGu Zheng <guz.fnst@cn.fujitsu.com>2014-04-11 05:50:00 -0400
committerJaegeuk Kim <jaegeuk.kim@samsung.com>2014-05-06 21:21:55 -0400
commit876dc59eb1f0131c092803d0d206d47dd0119dfe (patch)
treeaab91a229ed656fa30000c5112b52206cc69cfbe
parent8abfb36ab396377ea712cd640c525fd5535d1dc9 (diff)
f2fs: add the flush_merge handle in the remount flow
Add the *remount* handle of flush_merge option, so that the users can enable flush_merge in the runtime, such as the underlying device handles the cache_flush command relatively slowly. Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com> Signed-off-by: Jaegeuk Kim <jaegeuk.kim@samsung.com>
-rw-r--r--fs/f2fs/f2fs.h1
-rw-r--r--fs/f2fs/segment.c2
-rw-r--r--fs/f2fs/super.c45
3 files changed, 45 insertions, 3 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index d3180f8c0f97..55152de1118c 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -1177,6 +1177,7 @@ void destroy_node_manager_caches(void);
1177 */ 1177 */
1178void f2fs_balance_fs(struct f2fs_sb_info *); 1178void f2fs_balance_fs(struct f2fs_sb_info *);
1179void f2fs_balance_fs_bg(struct f2fs_sb_info *); 1179void f2fs_balance_fs_bg(struct f2fs_sb_info *);
1180int issue_flush_thread(void *);
1180int f2fs_issue_flush(struct f2fs_sb_info *); 1181int f2fs_issue_flush(struct f2fs_sb_info *);
1181void invalidate_blocks(struct f2fs_sb_info *, block_t); 1182void invalidate_blocks(struct f2fs_sb_info *, block_t);
1182void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t); 1183void refresh_sit_entry(struct f2fs_sb_info *, block_t, block_t);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 9993f94848fc..f6816e18db98 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -197,7 +197,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)
197 f2fs_sync_fs(sbi->sb, true); 197 f2fs_sync_fs(sbi->sb, true);
198} 198}
199 199
200static int issue_flush_thread(void *data) 200int issue_flush_thread(void *data)
201{ 201{
202 struct f2fs_sb_info *sbi = data; 202 struct f2fs_sb_info *sbi = data;
203 struct f2fs_sm_info *sm_i = SM_I(sbi); 203 struct f2fs_sm_info *sm_i = SM_I(sbi);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 5e20d2a36eac..bea642aec0fe 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -594,6 +594,8 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
594 struct f2fs_sb_info *sbi = F2FS_SB(sb); 594 struct f2fs_sb_info *sbi = F2FS_SB(sb);
595 struct f2fs_mount_info org_mount_opt; 595 struct f2fs_mount_info org_mount_opt;
596 int err, active_logs; 596 int err, active_logs;
597 bool need_restart_gc = false;
598 bool need_stop_gc = false;
597 599
598 sync_filesystem(sb); 600 sync_filesystem(sb);
599 601
@@ -611,7 +613,7 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
611 613
612 /* 614 /*
613 * Previous and new state of filesystem is RO, 615 * Previous and new state of filesystem is RO,
614 * so no point in checking GC conditions. 616 * so skip checking GC and FLUSH_MERGE conditions.
615 */ 617 */
616 if ((sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) 618 if ((sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY))
617 goto skip; 619 goto skip;
@@ -625,18 +627,57 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data)
625 if (sbi->gc_thread) { 627 if (sbi->gc_thread) {
626 stop_gc_thread(sbi); 628 stop_gc_thread(sbi);
627 f2fs_sync_fs(sb, 1); 629 f2fs_sync_fs(sb, 1);
630 need_restart_gc = true;
628 } 631 }
629 } else if (test_opt(sbi, BG_GC) && !sbi->gc_thread) { 632 } else if (test_opt(sbi, BG_GC) && !sbi->gc_thread) {
630 err = start_gc_thread(sbi); 633 err = start_gc_thread(sbi);
631 if (err) 634 if (err)
632 goto restore_opts; 635 goto restore_opts;
636 need_stop_gc = true;
637 }
638
639 /*
640 * We stop issue flush thread if FS is mounted as RO
641 * or if flush_merge is not passed in mount option.
642 */
643 if ((*flags & MS_RDONLY) || !test_opt(sbi, FLUSH_MERGE)) {
644 struct f2fs_sm_info *sm_info = sbi->sm_info;
645
646 if (sm_info->f2fs_issue_flush)
647 kthread_stop(sm_info->f2fs_issue_flush);
648 sm_info->issue_list = sm_info->dispatch_list = NULL;
649 sm_info->f2fs_issue_flush = NULL;
650 } else if (test_opt(sbi, FLUSH_MERGE)) {
651 struct f2fs_sm_info *sm_info = sbi->sm_info;
652
653 if (!sm_info->f2fs_issue_flush) {
654 dev_t dev = sbi->sb->s_bdev->bd_dev;
655
656 spin_lock_init(&sm_info->issue_lock);
657 init_waitqueue_head(&sm_info->flush_wait_queue);
658 sm_info->f2fs_issue_flush =
659 kthread_run(issue_flush_thread, sbi,
660 "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev));
661 if (IS_ERR(sm_info->f2fs_issue_flush)) {
662 err = PTR_ERR(sm_info->f2fs_issue_flush);
663 sm_info->f2fs_issue_flush = NULL;
664 goto restore_gc;
665 }
666 }
633 } 667 }
634skip: 668skip:
635 /* Update the POSIXACL Flag */ 669 /* Update the POSIXACL Flag */
636 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | 670 sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
637 (test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0); 671 (test_opt(sbi, POSIX_ACL) ? MS_POSIXACL : 0);
638 return 0; 672 return 0;
639 673restore_gc:
674 if (need_restart_gc) {
675 if (start_gc_thread(sbi))
676 f2fs_msg(sbi->sb, KERN_WARNING,
677 "background gc thread is stop");
678 } else if (need_stop_gc) {
679 stop_gc_thread(sbi);
680 }
640restore_opts: 681restore_opts:
641 sbi->mount_opt = org_mount_opt; 682 sbi->mount_opt = org_mount_opt;
642 sbi->active_logs = active_logs; 683 sbi->active_logs = active_logs;