aboutsummaryrefslogtreecommitdiffstats
path: root/fs/f2fs/gc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/f2fs/gc.c')
-rw-r--r--fs/f2fs/gc.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 14961593e93c..35f9b1a196aa 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -76,7 +76,9 @@ static int gc_thread_func(void *data)
76 else 76 else
77 wait_ms = increase_sleep_time(wait_ms); 77 wait_ms = increase_sleep_time(wait_ms);
78 78
79#ifdef CONFIG_F2FS_STAT_FS
79 sbi->bg_gc++; 80 sbi->bg_gc++;
81#endif
80 82
81 /* if return value is not zero, no victim was selected */ 83 /* if return value is not zero, no victim was selected */
82 if (f2fs_gc(sbi)) 84 if (f2fs_gc(sbi))
@@ -89,23 +91,28 @@ int start_gc_thread(struct f2fs_sb_info *sbi)
89{ 91{
90 struct f2fs_gc_kthread *gc_th; 92 struct f2fs_gc_kthread *gc_th;
91 dev_t dev = sbi->sb->s_bdev->bd_dev; 93 dev_t dev = sbi->sb->s_bdev->bd_dev;
94 int err = 0;
92 95
93 if (!test_opt(sbi, BG_GC)) 96 if (!test_opt(sbi, BG_GC))
94 return 0; 97 goto out;
95 gc_th = kmalloc(sizeof(struct f2fs_gc_kthread), GFP_KERNEL); 98 gc_th = kmalloc(sizeof(struct f2fs_gc_kthread), GFP_KERNEL);
96 if (!gc_th) 99 if (!gc_th) {
97 return -ENOMEM; 100 err = -ENOMEM;
101 goto out;
102 }
98 103
99 sbi->gc_thread = gc_th; 104 sbi->gc_thread = gc_th;
100 init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head); 105 init_waitqueue_head(&sbi->gc_thread->gc_wait_queue_head);
101 sbi->gc_thread->f2fs_gc_task = kthread_run(gc_thread_func, sbi, 106 sbi->gc_thread->f2fs_gc_task = kthread_run(gc_thread_func, sbi,
102 "f2fs_gc-%u:%u", MAJOR(dev), MINOR(dev)); 107 "f2fs_gc-%u:%u", MAJOR(dev), MINOR(dev));
103 if (IS_ERR(gc_th->f2fs_gc_task)) { 108 if (IS_ERR(gc_th->f2fs_gc_task)) {
109 err = PTR_ERR(gc_th->f2fs_gc_task);
104 kfree(gc_th); 110 kfree(gc_th);
105 sbi->gc_thread = NULL; 111 sbi->gc_thread = NULL;
106 return -ENOMEM;
107 } 112 }
108 return 0; 113
114out:
115 return err;
109} 116}
110 117
111void stop_gc_thread(struct f2fs_sb_info *sbi) 118void stop_gc_thread(struct f2fs_sb_info *sbi)
@@ -234,14 +241,14 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
234{ 241{
235 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); 242 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
236 struct victim_sel_policy p; 243 struct victim_sel_policy p;
237 unsigned int secno; 244 unsigned int secno, max_cost;
238 int nsearched = 0; 245 int nsearched = 0;
239 246
240 p.alloc_mode = alloc_mode; 247 p.alloc_mode = alloc_mode;
241 select_policy(sbi, gc_type, type, &p); 248 select_policy(sbi, gc_type, type, &p);
242 249
243 p.min_segno = NULL_SEGNO; 250 p.min_segno = NULL_SEGNO;
244 p.min_cost = get_max_cost(sbi, &p); 251 p.min_cost = max_cost = get_max_cost(sbi, &p);
245 252
246 mutex_lock(&dirty_i->seglist_lock); 253 mutex_lock(&dirty_i->seglist_lock);
247 254
@@ -280,7 +287,7 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
280 p.min_cost = cost; 287 p.min_cost = cost;
281 } 288 }
282 289
283 if (cost == get_max_cost(sbi, &p)) 290 if (cost == max_cost)
284 continue; 291 continue;
285 292
286 if (nsearched++ >= MAX_VICTIM_SEARCH) { 293 if (nsearched++ >= MAX_VICTIM_SEARCH) {
@@ -288,8 +295,8 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
288 break; 295 break;
289 } 296 }
290 } 297 }
291got_it:
292 if (p.min_segno != NULL_SEGNO) { 298 if (p.min_segno != NULL_SEGNO) {
299got_it:
293 if (p.alloc_mode == LFS) { 300 if (p.alloc_mode == LFS) {
294 secno = GET_SECNO(sbi, p.min_segno); 301 secno = GET_SECNO(sbi, p.min_segno);
295 if (gc_type == FG_GC) 302 if (gc_type == FG_GC)
@@ -314,28 +321,21 @@ static const struct victim_selection default_v_ops = {
314 321
315static struct inode *find_gc_inode(nid_t ino, struct list_head *ilist) 322static struct inode *find_gc_inode(nid_t ino, struct list_head *ilist)
316{ 323{
317 struct list_head *this;
318 struct inode_entry *ie; 324 struct inode_entry *ie;
319 325
320 list_for_each(this, ilist) { 326 list_for_each_entry(ie, ilist, list)
321 ie = list_entry(this, struct inode_entry, list);
322 if (ie->inode->i_ino == ino) 327 if (ie->inode->i_ino == ino)
323 return ie->inode; 328 return ie->inode;
324 }
325 return NULL; 329 return NULL;
326} 330}
327 331
328static void add_gc_inode(struct inode *inode, struct list_head *ilist) 332static void add_gc_inode(struct inode *inode, struct list_head *ilist)
329{ 333{
330 struct list_head *this; 334 struct inode_entry *new_ie;
331 struct inode_entry *new_ie, *ie;
332 335
333 list_for_each(this, ilist) { 336 if (inode == find_gc_inode(inode->i_ino, ilist)) {
334 ie = list_entry(this, struct inode_entry, list); 337 iput(inode);
335 if (ie->inode == inode) { 338 return;
336 iput(inode);
337 return;
338 }
339 } 339 }
340repeat: 340repeat:
341 new_ie = kmem_cache_alloc(winode_slab, GFP_NOFS); 341 new_ie = kmem_cache_alloc(winode_slab, GFP_NOFS);