diff options
Diffstat (limited to 'fs/f2fs/segment.h')
| -rw-r--r-- | fs/f2fs/segment.h | 57 | 
1 files changed, 40 insertions, 17 deletions
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index efdb7fc3b797..2ca8fb5d0dc4 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -104,6 +104,9 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi,  #define CAP_BLKS_PER_SEC(sbi)					\  	((sbi)->segs_per_sec * (sbi)->blocks_per_seg -		\  	 (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)				\  	(((segno) == -1) ? -1: (segno) / (sbi)->segs_per_sec)  #define GET_SEG_FROM_SEC(sbi, secno)				\ @@ -286,7 +289,6 @@ enum dirty_type {  };  struct dirty_seglist_info { -	const struct victim_selection *v_ops;	/* victim selction operation */  	unsigned long *dirty_segmap[NR_DIRTY_TYPE];  	unsigned long *dirty_secmap;  	struct mutex seglist_lock;		/* lock for segment bitmaps */ @@ -297,12 +299,6 @@ struct dirty_seglist_info {  	bool enable_pin_section;		/* enable pinning section */  }; -/* victim selection function for cleaning and SSR */ -struct victim_selection { -	int (*get_victim)(struct f2fs_sb_info *, unsigned int *, -					int, int, char, unsigned long long); -}; -  /* for active log information */  struct curseg_info {  	struct mutex curseg_mutex;		/* lock for consistency */ @@ -599,8 +595,12 @@ static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi,  	return true;  } -static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi, -					int freed, int needed) +/* + * calculate needed sections for dirty node/dentry + * and call has_curseg_enough_space + */ +static inline void __get_secs_required(struct f2fs_sb_info *sbi, +		unsigned int *lower_p, unsigned int *upper_p, bool *curseg_p)  {  	unsigned int total_node_blocks = get_pages(sbi, F2FS_DIRTY_NODES) +  					get_pages(sbi, F2FS_DIRTY_DENTS) + @@ -610,27 +610,50 @@ static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi,  	unsigned int dent_secs = total_dent_blocks / CAP_BLKS_PER_SEC(sbi);  	unsigned int node_blocks = total_node_blocks % CAP_BLKS_PER_SEC(sbi);  	unsigned int dent_blocks = total_dent_blocks % CAP_BLKS_PER_SEC(sbi); -	unsigned int free, need_lower, need_upper; + +	if (lower_p) +		*lower_p = node_secs + dent_secs; +	if (upper_p) +		*upper_p = node_secs + dent_secs + +			(node_blocks ? 1 : 0) + (dent_blocks ? 1 : 0); +	if (curseg_p) +		*curseg_p = has_curseg_enough_space(sbi, +				node_blocks, dent_blocks); +} + +static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi, +					int freed, int needed) +{ +	unsigned int free_secs, lower_secs, upper_secs; +	bool curseg_space;  	if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))  		return false; -	free = free_sections(sbi) + freed; -	need_lower = node_secs + dent_secs + reserved_sections(sbi) + needed; -	need_upper = need_lower + (node_blocks ? 1 : 0) + (dent_blocks ? 1 : 0); +	__get_secs_required(sbi, &lower_secs, &upper_secs, &curseg_space); + +	free_secs = free_sections(sbi) + freed; +	lower_secs += needed + reserved_sections(sbi); +	upper_secs += needed + reserved_sections(sbi); -	if (free > need_upper) +	if (free_secs > upper_secs)  		return false; -	else if (free <= need_lower) +	else if (free_secs <= lower_secs)  		return true; -	return !has_curseg_enough_space(sbi, node_blocks, dent_blocks); +	return !curseg_space; +} + +static inline bool has_enough_free_secs(struct f2fs_sb_info *sbi, +					int freed, int needed) +{ +	return !has_not_enough_free_secs(sbi, freed, needed);  }  static inline bool f2fs_is_checkpoint_ready(struct f2fs_sb_info *sbi)  {  	if (likely(!is_sbi_flag_set(sbi, SBI_CP_DISABLED)))  		return true; -	if (likely(!has_not_enough_free_secs(sbi, 0, 0))) +	if (likely(has_enough_free_secs(sbi, 0, 0)))  		return true;  	return false;  }  |