| .. | .. |
|---|
| 1547 | 1547 | if (i + 1 < dpolicy->granularity) |
|---|
| 1548 | 1548 | break; |
|---|
| 1549 | 1549 | |
|---|
| 1550 | | - if (i < DEFAULT_DISCARD_GRANULARITY && dpolicy->ordered) |
|---|
| 1550 | + if (i + 1 < DEFAULT_DISCARD_GRANULARITY && dpolicy->ordered) |
|---|
| 1551 | 1551 | return __issue_discard_cmd_orderly(sbi, dpolicy); |
|---|
| 1552 | 1552 | |
|---|
| 1553 | 1553 | pend_list = &dcc->pend_list[i]; |
|---|
| .. | .. |
|---|
| 4713 | 4713 | dirty_i->victim_secmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL); |
|---|
| 4714 | 4714 | if (!dirty_i->victim_secmap) |
|---|
| 4715 | 4715 | return -ENOMEM; |
|---|
| 4716 | + |
|---|
| 4717 | + dirty_i->pinned_secmap = f2fs_kvzalloc(sbi, bitmap_size, GFP_KERNEL); |
|---|
| 4718 | + if (!dirty_i->pinned_secmap) |
|---|
| 4719 | + return -ENOMEM; |
|---|
| 4720 | + |
|---|
| 4721 | + dirty_i->pinned_secmap_cnt = 0; |
|---|
| 4722 | + dirty_i->enable_pin_section = true; |
|---|
| 4716 | 4723 | return 0; |
|---|
| 4717 | 4724 | } |
|---|
| 4718 | 4725 | |
|---|
| .. | .. |
|---|
| 5047 | 5054 | return 0; |
|---|
| 5048 | 5055 | } |
|---|
| 5049 | 5056 | |
|---|
| 5050 | | -static bool is_conv_zone(struct f2fs_sb_info *sbi, unsigned int zone_idx, |
|---|
| 5051 | | - unsigned int dev_idx) |
|---|
| 5052 | | -{ |
|---|
| 5053 | | - if (!bdev_is_zoned(FDEV(dev_idx).bdev)) |
|---|
| 5054 | | - return true; |
|---|
| 5055 | | - return !test_bit(zone_idx, FDEV(dev_idx).blkz_seq); |
|---|
| 5056 | | -} |
|---|
| 5057 | | - |
|---|
| 5058 | | -/* Return the zone index in the given device */ |
|---|
| 5059 | | -static unsigned int get_zone_idx(struct f2fs_sb_info *sbi, unsigned int secno, |
|---|
| 5060 | | - int dev_idx) |
|---|
| 5061 | | -{ |
|---|
| 5062 | | - block_t sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno)); |
|---|
| 5063 | | - |
|---|
| 5064 | | - return (sec_start_blkaddr - FDEV(dev_idx).start_blk) >> |
|---|
| 5065 | | - sbi->log_blocks_per_blkz; |
|---|
| 5066 | | -} |
|---|
| 5067 | | - |
|---|
| 5068 | | -/* |
|---|
| 5069 | | - * Return the usable segments in a section based on the zone's |
|---|
| 5070 | | - * corresponding zone capacity. Zone is equal to a section. |
|---|
| 5071 | | - */ |
|---|
| 5072 | | -static inline unsigned int f2fs_usable_zone_segs_in_sec( |
|---|
| 5073 | | - struct f2fs_sb_info *sbi, unsigned int segno) |
|---|
| 5074 | | -{ |
|---|
| 5075 | | - unsigned int dev_idx, zone_idx, unusable_segs_in_sec; |
|---|
| 5076 | | - |
|---|
| 5077 | | - dev_idx = f2fs_target_device_index(sbi, START_BLOCK(sbi, segno)); |
|---|
| 5078 | | - zone_idx = get_zone_idx(sbi, GET_SEC_FROM_SEG(sbi, segno), dev_idx); |
|---|
| 5079 | | - |
|---|
| 5080 | | - /* Conventional zone's capacity is always equal to zone size */ |
|---|
| 5081 | | - if (is_conv_zone(sbi, zone_idx, dev_idx)) |
|---|
| 5082 | | - return sbi->segs_per_sec; |
|---|
| 5083 | | - |
|---|
| 5084 | | - /* |
|---|
| 5085 | | - * If the zone_capacity_blocks array is NULL, then zone capacity |
|---|
| 5086 | | - * is equal to the zone size for all zones |
|---|
| 5087 | | - */ |
|---|
| 5088 | | - if (!FDEV(dev_idx).zone_capacity_blocks) |
|---|
| 5089 | | - return sbi->segs_per_sec; |
|---|
| 5090 | | - |
|---|
| 5091 | | - /* Get the segment count beyond zone capacity block */ |
|---|
| 5092 | | - unusable_segs_in_sec = (sbi->blocks_per_blkz - |
|---|
| 5093 | | - FDEV(dev_idx).zone_capacity_blocks[zone_idx]) >> |
|---|
| 5094 | | - sbi->log_blocks_per_seg; |
|---|
| 5095 | | - return sbi->segs_per_sec - unusable_segs_in_sec; |
|---|
| 5096 | | -} |
|---|
| 5097 | | - |
|---|
| 5098 | 5057 | /* |
|---|
| 5099 | 5058 | * Return the number of usable blocks in a segment. The number of blocks |
|---|
| 5100 | 5059 | * returned is always equal to the number of blocks in a segment for |
|---|
| .. | .. |
|---|
| 5107 | 5066 | struct f2fs_sb_info *sbi, unsigned int segno) |
|---|
| 5108 | 5067 | { |
|---|
| 5109 | 5068 | block_t seg_start, sec_start_blkaddr, sec_cap_blkaddr; |
|---|
| 5110 | | - unsigned int zone_idx, dev_idx, secno; |
|---|
| 5069 | + unsigned int secno; |
|---|
| 5070 | + |
|---|
| 5071 | + if (!sbi->unusable_blocks_per_sec) |
|---|
| 5072 | + return sbi->blocks_per_seg; |
|---|
| 5111 | 5073 | |
|---|
| 5112 | 5074 | secno = GET_SEC_FROM_SEG(sbi, segno); |
|---|
| 5113 | 5075 | seg_start = START_BLOCK(sbi, segno); |
|---|
| 5114 | | - dev_idx = f2fs_target_device_index(sbi, seg_start); |
|---|
| 5115 | | - zone_idx = get_zone_idx(sbi, secno, dev_idx); |
|---|
| 5116 | | - |
|---|
| 5117 | | - /* |
|---|
| 5118 | | - * Conventional zone's capacity is always equal to zone size, |
|---|
| 5119 | | - * so, blocks per segment is unchanged. |
|---|
| 5120 | | - */ |
|---|
| 5121 | | - if (is_conv_zone(sbi, zone_idx, dev_idx)) |
|---|
| 5122 | | - return sbi->blocks_per_seg; |
|---|
| 5123 | | - |
|---|
| 5124 | | - if (!FDEV(dev_idx).zone_capacity_blocks) |
|---|
| 5125 | | - return sbi->blocks_per_seg; |
|---|
| 5126 | | - |
|---|
| 5127 | 5076 | sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno)); |
|---|
| 5128 | | - sec_cap_blkaddr = sec_start_blkaddr + |
|---|
| 5129 | | - FDEV(dev_idx).zone_capacity_blocks[zone_idx]; |
|---|
| 5077 | + sec_cap_blkaddr = sec_start_blkaddr + CAP_BLKS_PER_SEC(sbi); |
|---|
| 5130 | 5078 | |
|---|
| 5131 | 5079 | /* |
|---|
| 5132 | 5080 | * If segment starts before zone capacity and spans beyond |
|---|
| .. | .. |
|---|
| 5158 | 5106 | return 0; |
|---|
| 5159 | 5107 | } |
|---|
| 5160 | 5108 | |
|---|
| 5161 | | -static inline unsigned int f2fs_usable_zone_segs_in_sec(struct f2fs_sb_info *sbi, |
|---|
| 5162 | | - unsigned int segno) |
|---|
| 5163 | | -{ |
|---|
| 5164 | | - return 0; |
|---|
| 5165 | | -} |
|---|
| 5166 | 5109 | #endif |
|---|
| 5167 | 5110 | unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi, |
|---|
| 5168 | 5111 | unsigned int segno) |
|---|
| .. | .. |
|---|
| 5177 | 5120 | unsigned int segno) |
|---|
| 5178 | 5121 | { |
|---|
| 5179 | 5122 | if (f2fs_sb_has_blkzoned(sbi)) |
|---|
| 5180 | | - return f2fs_usable_zone_segs_in_sec(sbi, segno); |
|---|
| 5123 | + return CAP_SEGS_PER_SEC(sbi); |
|---|
| 5181 | 5124 | |
|---|
| 5182 | 5125 | return sbi->segs_per_sec; |
|---|
| 5183 | 5126 | } |
|---|
| .. | .. |
|---|
| 5301 | 5244 | { |
|---|
| 5302 | 5245 | struct dirty_seglist_info *dirty_i = DIRTY_I(sbi); |
|---|
| 5303 | 5246 | |
|---|
| 5247 | + kvfree(dirty_i->pinned_secmap); |
|---|
| 5304 | 5248 | kvfree(dirty_i->victim_secmap); |
|---|
| 5305 | 5249 | } |
|---|
| 5306 | 5250 | |
|---|