Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

f2fs: do not use discard_map for hard disks

We don't need to keep discard_map, if disk does not support discard command.

Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

+29 -10
+3 -1
fs/f2fs/debug.c
··· 154 154 si->base_mem += sizeof(struct sit_info); 155 155 si->base_mem += MAIN_SEGS(sbi) * sizeof(struct seg_entry); 156 156 si->base_mem += f2fs_bitmap_size(MAIN_SEGS(sbi)); 157 - si->base_mem += 3 * SIT_VBLOCK_MAP_SIZE * MAIN_SEGS(sbi); 157 + si->base_mem += 2 * SIT_VBLOCK_MAP_SIZE * MAIN_SEGS(sbi); 158 + if (f2fs_discard_en(sbi)) 159 + si->base_mem += SIT_VBLOCK_MAP_SIZE * MAIN_SEGS(sbi); 158 160 si->base_mem += SIT_VBLOCK_MAP_SIZE; 159 161 if (sbi->segs_per_sec > 1) 160 162 si->base_mem += MAIN_SECS(sbi) * sizeof(struct sec_entry);
+7
fs/f2fs/f2fs.h
··· 1072 1072 cp->ckpt_flags = cpu_to_le32(ckpt_flags); 1073 1073 } 1074 1074 1075 + static inline bool f2fs_discard_en(struct f2fs_sb_info *sbi) 1076 + { 1077 + struct request_queue *q = bdev_get_queue(sbi->sb->s_bdev); 1078 + 1079 + return blk_queue_discard(q); 1080 + } 1081 + 1075 1082 static inline void f2fs_lock_op(struct f2fs_sb_info *sbi) 1076 1083 { 1077 1084 down_read(&sbi->cp_rwsem);
+19 -9
fs/f2fs/segment.c
··· 660 660 bool force = (cpc->reason == CP_DISCARD); 661 661 int i; 662 662 663 - if (se->valid_blocks == max_blocks) 663 + if (se->valid_blocks == max_blocks || !f2fs_discard_en(sbi)) 664 664 return; 665 665 666 666 if (!force) { ··· 818 818 if (del > 0) { 819 819 if (f2fs_test_and_set_bit(offset, se->cur_valid_map)) 820 820 f2fs_bug_on(sbi, 1); 821 - if (!f2fs_test_and_set_bit(offset, se->discard_map)) 821 + if (f2fs_discard_en(sbi) && 822 + !f2fs_test_and_set_bit(offset, se->discard_map)) 822 823 sbi->discard_blks--; 823 824 } else { 824 825 if (!f2fs_test_and_clear_bit(offset, se->cur_valid_map)) 825 826 f2fs_bug_on(sbi, 1); 826 - if (f2fs_test_and_clear_bit(offset, se->discard_map)) 827 + if (f2fs_discard_en(sbi) && 828 + f2fs_test_and_clear_bit(offset, se->discard_map)) 827 829 sbi->discard_blks++; 828 830 } 829 831 if (!f2fs_test_bit(offset, se->ckpt_valid_map)) ··· 2129 2127 = kzalloc(SIT_VBLOCK_MAP_SIZE, GFP_KERNEL); 2130 2128 sit_i->sentries[start].ckpt_valid_map 2131 2129 = kzalloc(SIT_VBLOCK_MAP_SIZE, GFP_KERNEL); 2132 - sit_i->sentries[start].discard_map 2133 - = kzalloc(SIT_VBLOCK_MAP_SIZE, GFP_KERNEL); 2134 2130 if (!sit_i->sentries[start].cur_valid_map || 2135 - !sit_i->sentries[start].ckpt_valid_map || 2136 - !sit_i->sentries[start].discard_map) 2131 + !sit_i->sentries[start].ckpt_valid_map) 2137 2132 return -ENOMEM; 2133 + 2134 + if (f2fs_discard_en(sbi)) { 2135 + sit_i->sentries[start].discard_map 2136 + = kzalloc(SIT_VBLOCK_MAP_SIZE, GFP_KERNEL); 2137 + if (!sit_i->sentries[start].discard_map) 2138 + return -ENOMEM; 2139 + } 2138 2140 } 2139 2141 2140 2142 sit_i->tmp_map = kzalloc(SIT_VBLOCK_MAP_SIZE, GFP_KERNEL); ··· 2282 2276 seg_info_from_raw_sit(se, &sit); 2283 2277 2284 2278 /* build discard map only one time */ 2285 - memcpy(se->discard_map, se->cur_valid_map, SIT_VBLOCK_MAP_SIZE); 2286 - sbi->discard_blks += sbi->blocks_per_seg - se->valid_blocks; 2279 + if (f2fs_discard_en(sbi)) { 2280 + memcpy(se->discard_map, se->cur_valid_map, 2281 + SIT_VBLOCK_MAP_SIZE); 2282 + sbi->discard_blks += sbi->blocks_per_seg - 2283 + se->valid_blocks; 2284 + } 2287 2285 2288 2286 if (sbi->segs_per_sec > 1) { 2289 2287 struct sec_entry *e = get_sec_entry(sbi, start);