Commit 0b37ed21 authored by Jaegeuk Kim's avatar Jaegeuk Kim

f2fs: apply zone capacity to all zone type

If we manage the zone capacity per zone type, it'll break the GC assumption.
And, the current logic complains valid block count mismatch.
Let's apply zone capacity to all zone type, if specified.

Fixes: de881df9 ("f2fs: support zone capacity less than zone size")
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent b822dc91
...@@ -5003,48 +5003,6 @@ int f2fs_check_write_pointer(struct f2fs_sb_info *sbi) ...@@ -5003,48 +5003,6 @@ int f2fs_check_write_pointer(struct f2fs_sb_info *sbi)
return 0; return 0;
} }
static bool is_conv_zone(struct f2fs_sb_info *sbi, unsigned int zone_idx,
unsigned int dev_idx)
{
if (!bdev_is_zoned(FDEV(dev_idx).bdev))
return true;
return !test_bit(zone_idx, FDEV(dev_idx).blkz_seq);
}
/* Return the zone index in the given device */
static unsigned int get_zone_idx(struct f2fs_sb_info *sbi, unsigned int secno,
int dev_idx)
{
block_t sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno));
return (sec_start_blkaddr - FDEV(dev_idx).start_blk) >>
sbi->log_blocks_per_blkz;
}
/*
* Return the usable segments in a section based on the zone's
* corresponding zone capacity. Zone is equal to a section.
*/
static inline unsigned int f2fs_usable_zone_segs_in_sec(
struct f2fs_sb_info *sbi, unsigned int segno)
{
unsigned int dev_idx, zone_idx;
dev_idx = f2fs_target_device_index(sbi, START_BLOCK(sbi, segno));
zone_idx = get_zone_idx(sbi, GET_SEC_FROM_SEG(sbi, segno), dev_idx);
/* Conventional zone's capacity is always equal to zone size */
if (is_conv_zone(sbi, zone_idx, dev_idx))
return sbi->segs_per_sec;
if (!sbi->unusable_blocks_per_sec)
return sbi->segs_per_sec;
/* Get the segment count beyond zone capacity block */
return sbi->segs_per_sec - (sbi->unusable_blocks_per_sec >>
sbi->log_blocks_per_seg);
}
/* /*
* Return the number of usable blocks in a segment. The number of blocks * Return the number of usable blocks in a segment. The number of blocks
* returned is always equal to the number of blocks in a segment for * returned is always equal to the number of blocks in a segment for
...@@ -5057,23 +5015,13 @@ static inline unsigned int f2fs_usable_zone_blks_in_seg( ...@@ -5057,23 +5015,13 @@ static inline unsigned int f2fs_usable_zone_blks_in_seg(
struct f2fs_sb_info *sbi, unsigned int segno) struct f2fs_sb_info *sbi, unsigned int segno)
{ {
block_t seg_start, sec_start_blkaddr, sec_cap_blkaddr; block_t seg_start, sec_start_blkaddr, sec_cap_blkaddr;
unsigned int zone_idx, dev_idx, secno; unsigned int secno;
secno = GET_SEC_FROM_SEG(sbi, segno);
seg_start = START_BLOCK(sbi, segno);
dev_idx = f2fs_target_device_index(sbi, seg_start);
zone_idx = get_zone_idx(sbi, secno, dev_idx);
/*
* Conventional zone's capacity is always equal to zone size,
* so, blocks per segment is unchanged.
*/
if (is_conv_zone(sbi, zone_idx, dev_idx))
return sbi->blocks_per_seg;
if (!sbi->unusable_blocks_per_sec) if (!sbi->unusable_blocks_per_sec)
return sbi->blocks_per_seg; return sbi->blocks_per_seg;
secno = GET_SEC_FROM_SEG(sbi, segno);
seg_start = START_BLOCK(sbi, segno);
sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno)); sec_start_blkaddr = START_BLOCK(sbi, GET_SEG_FROM_SEC(sbi, secno));
sec_cap_blkaddr = sec_start_blkaddr + CAP_BLKS_PER_SEC(sbi); sec_cap_blkaddr = sec_start_blkaddr + CAP_BLKS_PER_SEC(sbi);
...@@ -5107,11 +5055,6 @@ static inline unsigned int f2fs_usable_zone_blks_in_seg(struct f2fs_sb_info *sbi ...@@ -5107,11 +5055,6 @@ static inline unsigned int f2fs_usable_zone_blks_in_seg(struct f2fs_sb_info *sbi
return 0; return 0;
} }
static inline unsigned int f2fs_usable_zone_segs_in_sec(struct f2fs_sb_info *sbi,
unsigned int segno)
{
return 0;
}
#endif #endif
unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi, unsigned int f2fs_usable_blks_in_seg(struct f2fs_sb_info *sbi,
unsigned int segno) unsigned int segno)
...@@ -5126,7 +5069,7 @@ unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi, ...@@ -5126,7 +5069,7 @@ unsigned int f2fs_usable_segs_in_sec(struct f2fs_sb_info *sbi,
unsigned int segno) unsigned int segno)
{ {
if (f2fs_sb_has_blkzoned(sbi)) if (f2fs_sb_has_blkzoned(sbi))
return f2fs_usable_zone_segs_in_sec(sbi, segno); return CAP_SEGS_PER_SEC(sbi);
return sbi->segs_per_sec; return sbi->segs_per_sec;
} }
......
...@@ -104,6 +104,9 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi, ...@@ -104,6 +104,9 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi,
#define CAP_BLKS_PER_SEC(sbi) \ #define CAP_BLKS_PER_SEC(sbi) \
((sbi)->segs_per_sec * (sbi)->blocks_per_seg - \ ((sbi)->segs_per_sec * (sbi)->blocks_per_seg - \
(sbi)->unusable_blocks_per_sec) (sbi)->unusable_blocks_per_sec)
#define CAP_SEGS_PER_SEC(sbi) \
((sbi)->segs_per_sec - ((sbi)->unusable_blocks_per_sec >>\
(sbi)->log_blocks_per_seg))
#define GET_SEC_FROM_SEG(sbi, segno) \ #define GET_SEC_FROM_SEG(sbi, segno) \
(((segno) == -1) ? -1: (segno) / (sbi)->segs_per_sec) (((segno) == -1) ? -1: (segno) / (sbi)->segs_per_sec)
#define GET_SEG_FROM_SEC(sbi, secno) \ #define GET_SEG_FROM_SEC(sbi, secno) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment