diff options
author | Gu Zheng <guz.fnst@cn.fujitsu.com> | 2014-04-27 14:21:21 +0800 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk.kim@samsung.com> | 2014-05-07 10:21:56 +0900 |
commit | a688b9d9e5cbec76edab74e724297b5488c07829 (patch) | |
tree | 3f9f4542c5c13648c7d96721c0cd65a0e9e8ead7 /fs/f2fs | |
parent | 6403eb1f646a49cc92f25c08f8716f8870a4a865 (diff) | |
download | linux-a688b9d9e5cbec76edab74e724297b5488c07829.tar.bz2 |
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>
Diffstat (limited to 'fs/f2fs')
-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 { int ret; }; +struct flush_cmd_control { + struct task_struct *f2fs_issue_flush; /* flush thread */ + wait_queue_head_t flush_wait_queue; /* waiting queue for wake-up */ + struct flush_cmd *issue_list; /* list for command issue */ + struct flush_cmd *dispatch_list; /* list for command dispatch */ + spinlock_t issue_lock; /* for issue list lock */ + struct flush_cmd *issue_tail; /* list tail of issue list */ +}; + struct f2fs_sm_info { struct sit_info *sit_info; /* whole segment information */ struct free_segmap_info *free_info; /* free segment information */ @@ -355,12 +364,8 @@ struct f2fs_sm_info { unsigned int min_ipu_util; /* in-place-update threshold */ /* for flush command control */ - struct task_struct *f2fs_issue_flush; /* flush thread */ - wait_queue_head_t flush_wait_queue; /* waiting queue for wake-up */ - struct flush_cmd *issue_list; /* list for command issue */ - struct flush_cmd *dispatch_list; /* list for command dispatch */ - spinlock_t issue_lock; /* for issue list lock */ - struct flush_cmd *issue_tail; /* list tail of issue list */ + struct flush_cmd_control *cmd_control_info; + }; /* 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) int issue_flush_thread(void *data) { struct f2fs_sb_info *sbi = data; - struct f2fs_sm_info *sm_i = SM_I(sbi); - wait_queue_head_t *q = &sm_i->flush_wait_queue; + struct flush_cmd_control *fcc = SM_I(sbi)->cmd_control_info; + wait_queue_head_t *q = &fcc->flush_wait_queue; repeat: if (kthread_should_stop()) return 0; - spin_lock(&sm_i->issue_lock); - if (sm_i->issue_list) { - sm_i->dispatch_list = sm_i->issue_list; - sm_i->issue_list = sm_i->issue_tail = NULL; + spin_lock(&fcc->issue_lock); + if (fcc->issue_list) { + fcc->dispatch_list = fcc->issue_list; + fcc->issue_list = fcc->issue_tail = NULL; } - spin_unlock(&sm_i->issue_lock); + spin_unlock(&fcc->issue_lock); - if (sm_i->dispatch_list) { + if (fcc->dispatch_list) { struct bio *bio = bio_alloc(GFP_NOIO, 0); struct flush_cmd *cmd, *next; int ret; @@ -221,22 +221,23 @@ repeat: bio->bi_bdev = sbi->sb->s_bdev; ret = submit_bio_wait(WRITE_FLUSH, bio); - for (cmd = sm_i->dispatch_list; cmd; cmd = next) { + for (cmd = fcc->dispatch_list; cmd; cmd = next) { cmd->ret = ret; next = cmd->next; complete(&cmd->wait); } bio_put(bio); - sm_i->dispatch_list = NULL; + fcc->dispatch_list = NULL; } - wait_event_interruptible(*q, kthread_should_stop() || sm_i->issue_list); + wait_event_interruptible(*q, + kthread_should_stop() || fcc->issue_list); goto repeat; } int f2fs_issue_flush(struct f2fs_sb_info *sbi) { - struct f2fs_sm_info *sm_i = SM_I(sbi); + struct flush_cmd_control *fcc = SM_I(sbi)->cmd_control_info; struct flush_cmd *cmd; int ret; @@ -246,16 +247,16 @@ int f2fs_issue_flush(struct f2fs_sb_info *sbi) cmd = f2fs_kmem_cache_alloc(flush_cmd_slab, GFP_ATOMIC | __GFP_ZERO); init_completion(&cmd->wait); - spin_lock(&sm_i->issue_lock); - if (sm_i->issue_list) - sm_i->issue_tail->next = cmd; + spin_lock(&fcc->issue_lock); + if (fcc->issue_list) + fcc->issue_tail->next = cmd; else - sm_i->issue_list = cmd; - sm_i->issue_tail = cmd; - spin_unlock(&sm_i->issue_lock); + fcc->issue_list = cmd; + fcc->issue_tail = cmd; + spin_unlock(&fcc->issue_lock); - if (!sm_i->dispatch_list) - wake_up(&sm_i->flush_wait_queue); + if (!fcc->dispatch_list) + wake_up(&fcc->flush_wait_queue); wait_for_completion(&cmd->wait); ret = cmd->ret; @@ -1873,12 +1874,22 @@ int build_segment_manager(struct f2fs_sb_info *sbi) sm_info->max_discards = 0; if (test_opt(sbi, FLUSH_MERGE) && !f2fs_readonly(sbi->sb)) { - spin_lock_init(&sm_info->issue_lock); - init_waitqueue_head(&sm_info->flush_wait_queue); - sm_info->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, + struct flush_cmd_control *fcc = + kzalloc(sizeof(struct flush_cmd_control), GFP_KERNEL); + + if (!fcc) + return -ENOMEM; + spin_lock_init(&fcc->issue_lock); + init_waitqueue_head(&fcc->flush_wait_queue); + + fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); - if (IS_ERR(sm_info->f2fs_issue_flush)) - return PTR_ERR(sm_info->f2fs_issue_flush); + if (IS_ERR(fcc->f2fs_issue_flush)) { + err = PTR_ERR(fcc->f2fs_issue_flush); + kfree(fcc); + return err; + } + sm_info->cmd_control_info = fcc; } err = build_sit_info(sbi); @@ -1987,10 +1998,14 @@ static void destroy_sit_info(struct f2fs_sb_info *sbi) void destroy_segment_manager(struct f2fs_sb_info *sbi) { struct f2fs_sm_info *sm_info = SM_I(sbi); + struct flush_cmd_control *fcc; + if (!sm_info) return; - if (sm_info->f2fs_issue_flush) - kthread_stop(sm_info->f2fs_issue_flush); + fcc = sm_info->cmd_control_info; + if (fcc && fcc->f2fs_issue_flush) + kthread_stop(fcc->f2fs_issue_flush); + kfree(fcc); destroy_dirty_segmap(sbi); destroy_curseg(sbi); 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) * or if flush_merge is not passed in mount option. */ if ((*flags & MS_RDONLY) || !test_opt(sbi, FLUSH_MERGE)) { - struct f2fs_sm_info *sm_info = sbi->sm_info; - - if (sm_info->f2fs_issue_flush) - kthread_stop(sm_info->f2fs_issue_flush); - sm_info->issue_list = sm_info->dispatch_list = NULL; - sm_info->f2fs_issue_flush = NULL; - } else if (test_opt(sbi, FLUSH_MERGE)) { - struct f2fs_sm_info *sm_info = sbi->sm_info; - - if (!sm_info->f2fs_issue_flush) { - dev_t dev = sbi->sb->s_bdev->bd_dev; - - spin_lock_init(&sm_info->issue_lock); - init_waitqueue_head(&sm_info->flush_wait_queue); - sm_info->f2fs_issue_flush = - kthread_run(issue_flush_thread, sbi, + struct flush_cmd_control *fcc = + sbi->sm_info->cmd_control_info; + + if (fcc && fcc->f2fs_issue_flush) + kthread_stop(fcc->f2fs_issue_flush); + kfree(fcc); + sbi->sm_info->cmd_control_info = NULL; + } else if (test_opt(sbi, FLUSH_MERGE) && + !sbi->sm_info->cmd_control_info) { + dev_t dev = sbi->sb->s_bdev->bd_dev; + struct flush_cmd_control *fcc = + kzalloc(sizeof(struct flush_cmd_control), GFP_KERNEL); + + if (!fcc) { + err = -ENOMEM; + goto restore_gc; + } + spin_lock_init(&fcc->issue_lock); + init_waitqueue_head(&fcc->flush_wait_queue); + fcc->f2fs_issue_flush = kthread_run(issue_flush_thread, sbi, "f2fs_flush-%u:%u", MAJOR(dev), MINOR(dev)); - if (IS_ERR(sm_info->f2fs_issue_flush)) { - err = PTR_ERR(sm_info->f2fs_issue_flush); - sm_info->f2fs_issue_flush = NULL; - goto restore_gc; - } + if (IS_ERR(fcc->f2fs_issue_flush)) { + err = PTR_ERR(fcc->f2fs_issue_flush); + kfree(fcc); + goto restore_gc; } + sbi->sm_info->cmd_control_info = fcc; } skip: /* Update the POSIXACL Flag */ |