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.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index 2e3eb2d4fc30..09b8a907400b 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -160,18 +160,21 @@ static unsigned int get_max_cost(struct f2fs_sb_info *sbi,
160static unsigned int check_bg_victims(struct f2fs_sb_info *sbi) 160static unsigned int check_bg_victims(struct f2fs_sb_info *sbi)
161{ 161{
162 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); 162 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
163 unsigned int segno; 163 unsigned int hint = 0;
164 unsigned int secno;
164 165
165 /* 166 /*
166 * If the gc_type is FG_GC, we can select victim segments 167 * If the gc_type is FG_GC, we can select victim segments
167 * selected by background GC before. 168 * selected by background GC before.
168 * Those segments guarantee they have small valid blocks. 169 * Those segments guarantee they have small valid blocks.
169 */ 170 */
170 segno = find_next_bit(dirty_i->victim_segmap[BG_GC], 171next:
171 TOTAL_SEGS(sbi), 0); 172 secno = find_next_bit(dirty_i->victim_secmap, TOTAL_SECS(sbi), hint++);
172 if (segno < TOTAL_SEGS(sbi)) { 173 if (secno < TOTAL_SECS(sbi)) {
173 clear_bit(segno, dirty_i->victim_segmap[BG_GC]); 174 if (sec_usage_check(sbi, secno))
174 return segno; 175 goto next;
176 clear_bit(secno, dirty_i->victim_secmap);
177 return secno * sbi->segs_per_sec;
175 } 178 }
176 return NULL_SEGNO; 179 return NULL_SEGNO;
177} 180}
@@ -234,7 +237,7 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
234{ 237{
235 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); 238 struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
236 struct victim_sel_policy p; 239 struct victim_sel_policy p;
237 unsigned int segno; 240 unsigned int secno;
238 int nsearched = 0; 241 int nsearched = 0;
239 242
240 p.alloc_mode = alloc_mode; 243 p.alloc_mode = alloc_mode;
@@ -253,6 +256,7 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
253 256
254 while (1) { 257 while (1) {
255 unsigned long cost; 258 unsigned long cost;
259 unsigned int segno;
256 260
257 segno = find_next_bit(p.dirty_segmap, 261 segno = find_next_bit(p.dirty_segmap,
258 TOTAL_SEGS(sbi), p.offset); 262 TOTAL_SEGS(sbi), p.offset);
@@ -265,13 +269,11 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
265 break; 269 break;
266 } 270 }
267 p.offset = ((segno / p.ofs_unit) * p.ofs_unit) + p.ofs_unit; 271 p.offset = ((segno / p.ofs_unit) * p.ofs_unit) + p.ofs_unit;
272 secno = GET_SECNO(sbi, segno);
268 273
269 if (test_bit(segno, dirty_i->victim_segmap[FG_GC])) 274 if (sec_usage_check(sbi, secno))
270 continue; 275 continue;
271 if (gc_type == BG_GC && 276 if (gc_type == BG_GC && test_bit(secno, dirty_i->victim_secmap))
272 test_bit(segno, dirty_i->victim_segmap[BG_GC]))
273 continue;
274 if (IS_CURSEC(sbi, GET_SECNO(sbi, segno)))
275 continue; 277 continue;
276 278
277 cost = get_gc_cost(sbi, segno, &p); 279 cost = get_gc_cost(sbi, segno, &p);
@@ -291,13 +293,14 @@ static int get_victim_by_default(struct f2fs_sb_info *sbi,
291 } 293 }
292got_it: 294got_it:
293 if (p.min_segno != NULL_SEGNO) { 295 if (p.min_segno != NULL_SEGNO) {
294 *result = (p.min_segno / p.ofs_unit) * p.ofs_unit;
295 if (p.alloc_mode == LFS) { 296 if (p.alloc_mode == LFS) {
296 int i; 297 secno = GET_SECNO(sbi, p.min_segno);
297 for (i = 0; i < p.ofs_unit; i++) 298 if (gc_type == FG_GC)
298 set_bit(*result + i, 299 sbi->cur_victim_sec = secno;
299 dirty_i->victim_segmap[gc_type]); 300 else
301 set_bit(secno, dirty_i->victim_secmap);
300 } 302 }
303 *result = (p.min_segno / p.ofs_unit) * p.ofs_unit;
301 } 304 }
302 mutex_unlock(&dirty_i->seglist_lock); 305 mutex_unlock(&dirty_i->seglist_lock);
303 306
@@ -662,9 +665,11 @@ gc_more:
662 for (i = 0; i < sbi->segs_per_sec; i++) 665 for (i = 0; i < sbi->segs_per_sec; i++)
663 do_garbage_collect(sbi, segno + i, &ilist, gc_type); 666 do_garbage_collect(sbi, segno + i, &ilist, gc_type);
664 667
665 if (gc_type == FG_GC && 668 if (gc_type == FG_GC) {
666 get_valid_blocks(sbi, segno, sbi->segs_per_sec) == 0) 669 sbi->cur_victim_sec = NULL_SEGNO;
667 nfree++; 670 nfree++;
671 WARN_ON(get_valid_blocks(sbi, segno, sbi->segs_per_sec));
672 }
668 673
669 if (has_not_enough_free_secs(sbi, nfree)) 674 if (has_not_enough_free_secs(sbi, nfree))
670 goto gc_more; 675 goto gc_more;