diff options
author | Gu Zheng <guz.fnst@cn.fujitsu.com> | 2014-04-27 02:21:21 -0400 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2014-05-06 21:21:56 -0400 |
commit | a688b9d9e5cbec76edab74e724297b5488c07829 (patch) | |
tree | 3f9f4542c5c13648c7d96721c0cd65a0e9e8ead7 | |
parent | 6403eb1f646a49cc92f25c08f8716f8870a4a865 (diff) |
f2fs: introduce struct flush_cmd_control to wrap the flush_merge fields
Split the flush_merge fields from sm_i, and use the new struct flush_cmd_control
to wrap it, so that we can igonre these fileds if flush_merge is disable, and
it alse can the structs more neat.
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.h | 17 | ||||
-rw-r--r-- | fs/f2fs/segment.c | 69 | ||||
-rw-r--r-- | fs/f2fs/super.c | 46 |
3 files changed, 78 insertions, 54 deletions
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 97da71d96ce3..fa0ec8116f48 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h | |||
@@ -325,6 +325,15 @@ struct flush_cmd { | |||
325 | int ret; | 325 | int ret; |
326 | }; | 326 | }; |
327 | 327 | ||
328 | struct flush_cmd_control { | ||
329 | struct task_struct *f2fs_issue_flush; /* flush thread */ | ||
330 | wait_queue_head_t flush_wait_queue; /* waiting queue for wake-up */ | ||
331 | struct flush_cmd *issue_list; /* list for command issue */ | ||
332 | struct flush_cmd *dispatch_list; /* list for command dispatch */ | ||
333 | spinlock_t issue_lock; /* for issue list lock */ | ||
334 | struct flush_cmd *issue_tail; /* list tail of issue list */ | ||
335 | }; | ||
336 | |||
328 | struct f2fs_sm_info { | 337 | struct f2fs_sm_info { |
329 | struct sit_info *sit_info; /* whole segment information */ | 338 | struct sit_info *sit_info; /* whole segment information */ |
330 | struct free_segmap_info *free_info; /* free segment information */ | 339 | struct free_segmap_info *free_info; /* free segment information */ |
@@ -355,12 +364,8 @@ struct f2fs_sm_info { | |||
355 | unsigned int min_ipu_util; /* in-place-update threshold */ | 364 | unsigned int min_ipu_util; /* in-place-update threshold */ |
356 | 365 | ||
357 | /* for flush command control */ | 366 | /* for flush command control */ |
358 | struct task_struct *f2fs_issue_flush; /* flush thread */ | 367 | struct flush_cmd_control *cmd_control_info; |
359 | wait_queue_head_t flush_wait_queue; /* waiting queue for wake-up */ | 368 | |
360 | struct flush_cmd *issue_list; /* list for command issue */ | ||
361 | struct flush_cmd *dispatch_list; /* list for command dispatch */ | ||
362 | spinlock_t issue_lock; /* for issue list lock */ | ||
363 | struct flush_cmd *issue_tail; /* list tail of issue list */ | ||
364 | }; | 369 | }; |
365 | 370 | ||
366 | /* | 371 | /* |
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index f6816e18db98..9ac4f861c6f6 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c | |||
@@ -200,20 +200,20 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi) | |||
200 | int issue_flush_thread(void *data) | 200 | int 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 flush_cmd_control *fcc = SM_I(sbi)->cmd_control_info; |
204 | wait_queue_head_t *q = &sm_i->flush_wait_queue; | 204 | wait_queue_head_t *q = &fcc->flush_wait_queue; |
205 | repeat: | 205 | repeat: |
206 | if (kthread_should_stop()) | 206 | if (kthread_should_stop()) |
207 | return 0; | 207 | return 0; |
208 | 208 | ||
209 | spin_lock(&sm_i->issue_lock); | 209 | spin_lock(&fcc->issue_lock); |
210 | if (sm_i->issue_list) { | 210 | if (fcc->issue_list) { |
211 | sm_i->dispatch_list = sm_i->issue_list; | 211 | fcc->dispatch_list = fcc->issue_list; |
212 | sm_i->issue_list = sm_i->issue_tail = NULL; | 212 | fcc->issue_list = fcc->issue_tail = NULL; |
213 | } | 213 | } |
214 | spin_unlock(&sm_i->issue_lock); | 214 | spin_unlock(&fcc->issue_lock); |
215 | 215 | ||
216 | if (sm_i->dispatch_list) { | 216 | if (fcc->dispatch_list) { |
217 | struct bio *bio = bio_alloc(GFP_NOIO, 0); | 217 | struct bio *bio = bio_alloc(GFP_NOIO, 0); |
218 | struct flush_cmd *cmd, *next; | 218 | struct flush_cmd *cmd, *next; |
219 | int ret; | 219 | int ret; |
@@ -221,22 +221,23 @@ repeat: | |||
221 | bio->bi_bdev = sbi->sb->s_bdev; | 221 | bio->bi_bdev = sbi->sb->s_bdev; |
222 | ret = submit_bio_wait(WRITE_FLUSH, bio); | 222 | ret = submit_bio_wait(WRITE_FLUSH, bio); |
223 | 223 | ||
224 | for (cmd = sm_i->dispatch_list; cmd; cmd = next) { | 224 | for (cmd = fcc->dispatch_list; cmd; cmd = next) { |
225 | cmd->ret = ret; | 225 | cmd->ret = ret; |
226 | next = cmd->next; | 226 | next = cmd->next; |
227 | complete(&cmd->wait); | 227 | complete(&cmd->wait); |
228 | } | 228 | } |
229 | bio_put(bio); | 229 | bio_put(bio); |
230 | sm_i->dispatch_list = NULL; | 230 | fcc->dispatch_list = NULL; |
231 | } | 231 | } |
232 | 232 | ||
233 | wait_event_interruptible(*q, kthread_should_stop() || sm_i->issue_list); | 233 | wait_event_interruptible(*q, |
234 | kthread_should_stop() || fcc->issue_list); | ||
234 | goto repeat; | 235 | goto repeat; |
235 | } | 236 | } |
236 | 237 | ||
237 | int f2fs_issue_flush(struct f2fs_sb_info *sbi) | 238 | int f2fs_issue_flush(struct f2fs_sb_info *sbi) |
238 | { | 239 | { |
239 | struct f2fs_sm_info *sm_i = SM_I(sbi); | 240 | struct flush_cmd_control *fcc = SM_I(sbi)->cmd_control_info; |
240 | struct flush_cmd *cmd; | 241 | struct flush_cmd *cmd; |
241 | int ret; | 242 | int ret; |
242 | 243 | ||
@@ -246,16 +247,16 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi) | |||
246 | cmd = f2fs_kmem_cache_alloc(flush_cmd_slab, GFP_ATOMIC | __GFP_ZERO); | 247 | cmd = f2fs_kmem_cache_alloc(flush_cmd_slab, GFP_ATOMIC | __GFP_ZERO); |
247 | init_completion(&cmd->wait); | 248 | init_completion(&cmd->wait); |
248 | 249 | ||
249 | spin_lock(&sm_i->issue_lock); | 250 | spin_lock(&fcc->issue_lock); |
250 | if (sm_i->issue_list) | 251 | if (fcc->issue_list) |
251 | sm_i->issue_tail->next = cmd; | 252 | fcc->issue_tail->next = cmd; |
252 | else | 253 | else |
253 | sm_i->issue_list = cmd; | 254 | fcc->issue_list = cmd; |
254 | sm_i->issue_tail = cmd; | 255 | fcc->issue_tail = cmd; |
255 | spin_unlock(&sm_i->issue_lock); | 256 | spin_unlock(&fcc->issue_lock); |
256 | 257 | ||
257 | if (!sm_i->dispatch_list) | 258 | if (!fcc->dispatch_list) |
258 | wake_up(&sm_i->flush_wait_queue); | 259 | wake_up(&fcc->flush_wait_queue); |
259 | 260 | ||
260 | wait_for_completion(&cmd->wait); | 261 | wait_for_completion(&cmd->wait); |
261 | ret = cmd->ret; | 262 | ret = cmd->ret; |
@@ -1873,12 +1874,22 @@ int build_segment_manager(struct f2fs_sb_info *sbi) | |||
1873 | sm_info->max_discards = 0; | 1874 | sm_info->max_discards = 0; |
1874 | 1875 | ||
1875 | if (test_opt(sbi, FLUSH_MERGE) && !f2fs_readonly(sbi->sb)) { | 1876 | if (test_opt(sbi, FLUSH_MERGE) && !f2fs_readonly(sbi->sb)) { |
1876 | spin_lock_init(&sm_info->issue_lock); | 1877 | struct flush_cmd_control *fcc = |
1877 | init_waitqueue_head(&sm_info->flush_wait_queue); | 1878 | kzalloc(sizeof(struct flush_cmd_control), GFP_KERNEL); |
1878 | sm_info->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, | 1879 | |
1880 | if (!fcc) | ||
1881 | return -ENOMEM; | ||
1882 | spin_lock_init(&fcc->issue_lock); | ||
1883 | init_waitqueue_head(&fcc->flush_wait_queue); | ||
1884 | |||
1885 | fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, | ||
1879 | "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); | 1886 | "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); |
1880 | if (IS_ERR(sm_info->f2fs_issue_flush)) | 1887 | if (IS_ERR(fcc->f2fs_issue_flush)) { |
1881 | return PTR_ERR(sm_info->f2fs_issue_flush); | 1888 | err = PTR_ERR(fcc->f2fs_issue_flush); |
1889 | kfree(fcc); | ||
1890 | return err; | ||
1891 | } | ||
1892 | sm_info->cmd_control_info = fcc; | ||
1882 | } | 1893 | } |
1883 | 1894 | ||
1884 | err = build_sit_info(sbi); | 1895 | err = build_sit_info(sbi); |
@@ -1987,10 +1998,14 @@ static void destroy_sit_info(struct f2fs_sb_info *sbi) | |||
1987 | void destroy_segment_manager(struct f2fs_sb_info *sbi) | 1998 | void destroy_segment_manager(struct f2fs_sb_info *sbi) |
1988 | { | 1999 | { |
1989 | struct f2fs_sm_info *sm_info = SM_I(sbi); | 2000 | struct f2fs_sm_info *sm_info = SM_I(sbi); |
2001 | struct flush_cmd_control *fcc; | ||
2002 | |||
1990 | if (!sm_info) | 2003 | if (!sm_info) |
1991 | return; | 2004 | return; |
1992 | if (sm_info->f2fs_issue_flush) | 2005 | fcc = sm_info->cmd_control_info; |
1993 | kthread_stop(sm_info->f2fs_issue_flush); | 2006 | if (fcc && fcc->f2fs_issue_flush) |
2007 | kthread_stop(fcc->f2fs_issue_flush); | ||
2008 | kfree(fcc); | ||
1994 | destroy_dirty_segmap(sbi); | 2009 | destroy_dirty_segmap(sbi); |
1995 | destroy_curseg(sbi); | 2010 | destroy_curseg(sbi); |
1996 | destroy_free_segmap(sbi); | 2011 | destroy_free_segmap(sbi); |
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index bea642aec0fe..a7ed92e2948a 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c | |||
@@ -641,29 +641,33 @@ static int f2fs_remount(struct super_block *sb, int *flags, char *data) | |||
641 | * or if flush_merge is not passed in mount option. | 641 | * or if flush_merge is not passed in mount option. |
642 | */ | 642 | */ |
643 | if ((*flags & MS_RDONLY) || !test_opt(sbi, FLUSH_MERGE)) { | 643 | if ((*flags & MS_RDONLY) || !test_opt(sbi, FLUSH_MERGE)) { |
644 | struct f2fs_sm_info *sm_info = sbi->sm_info; | 644 | struct flush_cmd_control *fcc = |
645 | 645 | sbi->sm_info->cmd_control_info; | |
646 | if (sm_info->f2fs_issue_flush) | 646 | |
647 | kthread_stop(sm_info->f2fs_issue_flush); | 647 | if (fcc && fcc->f2fs_issue_flush) |
648 | sm_info->issue_list = sm_info->dispatch_list = NULL; | 648 | kthread_stop(fcc->f2fs_issue_flush); |
649 | sm_info->f2fs_issue_flush = NULL; | 649 | kfree(fcc); |
650 | } else if (test_opt(sbi, FLUSH_MERGE)) { | 650 | sbi->sm_info->cmd_control_info = NULL; |
651 | struct f2fs_sm_info *sm_info = sbi->sm_info; | 651 | } else if (test_opt(sbi, FLUSH_MERGE) && |
652 | 652 | !sbi->sm_info->cmd_control_info) { | |
653 | if (!sm_info->f2fs_issue_flush) { | 653 | dev_t dev = sbi->sb->s_bdev->bd_dev; |
654 | dev_t dev = sbi->sb->s_bdev->bd_dev; | 654 | struct flush_cmd_control *fcc = |
655 | 655 | kzalloc(sizeof(struct flush_cmd_control), GFP_KERNEL); | |
656 | spin_lock_init(&sm_info->issue_lock); | 656 | |
657 | init_waitqueue_head(&sm_info->flush_wait_queue); | 657 | if (!fcc) { |
658 | sm_info->f2fs_issue_flush = | 658 | err = -ENOMEM; |
659 | kthread_run(issue_flush_thread, sbi, | 659 | goto restore_gc; |
660 | } | ||
661 | spin_lock_init(&fcc->issue_lock); | ||
662 | init_waitqueue_head(&fcc->flush_wait_queue); | ||
663 | fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, | ||
660 | "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); | 664 | "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); |
661 | if (IS_ERR(sm_info->f2fs_issue_flush)) { | 665 | if (IS_ERR(fcc->f2fs_issue_flush)) { |
662 | err = PTR_ERR(sm_info->f2fs_issue_flush); | 666 | err = PTR_ERR(fcc->f2fs_issue_flush); |
663 | sm_info->f2fs_issue_flush = NULL; | 667 | kfree(fcc); |
664 | goto restore_gc; | 668 | goto restore_gc; |
665 | } | ||
666 | } | 669 | } |
670 | sbi->sm_info->cmd_control_info = fcc; | ||
667 | } | 671 | } |
668 | skip: | 672 | skip: |
669 | /* Update the POSIXACL Flag */ | 673 | /* Update the POSIXACL Flag */ |