diff options
-rw-r--r-- | fs/f2fs/checkpoint.c | 11 | ||||
-rw-r--r-- | fs/f2fs/f2fs.h | 1 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 4 |
3 files changed, 14 insertions, 2 deletions
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index d80882763ffd..2a5999d865b2 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c | |||
@@ -757,8 +757,15 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, bool is_umount) | |||
757 | f2fs_put_page(cp_page, 1); | 757 | f2fs_put_page(cp_page, 1); |
758 | 758 | ||
759 | /* wait for previous submitted node/meta pages writeback */ | 759 | /* wait for previous submitted node/meta pages writeback */ |
760 | while (get_pages(sbi, F2FS_WRITEBACK)) | 760 | sbi->cp_task = current; |
761 | congestion_wait(BLK_RW_ASYNC, HZ / 50); | 761 | while (get_pages(sbi, F2FS_WRITEBACK)) { |
762 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
763 | if (!get_pages(sbi, F2FS_WRITEBACK)) | ||
764 | break; | ||
765 | io_schedule(); | ||
766 | } | ||
767 | __set_current_state(TASK_RUNNING); | ||
768 | sbi->cp_task = NULL; | ||
762 | 769 | ||
763 | filemap_fdatawait_range(sbi->node_inode->i_mapping, 0, LONG_MAX); | 770 | filemap_fdatawait_range(sbi->node_inode->i_mapping, 0, LONG_MAX); |
764 | filemap_fdatawait_range(sbi->meta_inode->i_mapping, 0, LONG_MAX); | 771 | filemap_fdatawait_range(sbi->meta_inode->i_mapping, 0, LONG_MAX); |
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 308967b71674..171c52fc95bb 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -362,6 +362,7 @@ struct f2fs_sb_info { | |||
362 | struct mutex writepages; /* mutex for writepages() */ | 362 | struct mutex writepages; /* mutex for writepages() */ |
363 | int por_doing; /* recovery is doing or not */ | 363 | int por_doing; /* recovery is doing or not */ |
364 | int on_build_free_nids; /* build_free_nids is doing */ | 364 | int on_build_free_nids; /* build_free_nids is doing */ |
365 | struct task_struct *cp_task; /* checkpoint task */ | ||
365 | 366 | ||
366 | /* for orphan inode management */ | 367 | /* for orphan inode management */ |
367 | struct list_head orphan_inode_list; /* orphan inode list */ | 368 | struct list_head orphan_inode_list; /* orphan inode list */ |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index bd79bbeceb1d..3b203597c744 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -597,6 +597,10 @@ static void f2fs_end_io_write(struct bio *bio, int err) | |||
597 | 597 | ||
598 | if (p->is_sync) | 598 | if (p->is_sync) |
599 | complete(p->wait); | 599 | complete(p->wait); |
600 | |||
601 | if (!get_pages(p->sbi, F2FS_WRITEBACK) && p->sbi->cp_task) | ||
602 | wake_up_process(p->sbi->cp_task); | ||
603 | |||
600 | kfree(p); | 604 | kfree(p); |
601 | bio_put(bio); | 605 | bio_put(bio); |
602 | } | 606 | } |