mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	f2fs: factor out victim_entry usage from general rb_tree use
Let's reduce the complexity of mixed use of rb_tree in victim_entry from
extent_cache and discard_cmd.
This should fix arm32 memory alignment issue caused by shared rb_entry.
[struct victim_entry]              [struct rb_entry]
[0] struct rb_node rb_node;        [0] struct rb_node rb_node;
                                       union {
                                         struct {
                                           unsigned int ofs;
                                           unsigned int len;
                                         };
[16] unsigned long long mtime;     [12] unsigned long long key;
                                       } __packed;
Cc: <stable@vger.kernel.org>
Fixes: 093749e296 ("f2fs: support age threshold based garbage collection")
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									c17caf0ba3
								
							
						
					
					
						commit
						043d2d00b4
					
				
					 5 changed files with 93 additions and 115 deletions
				
			
		| 
						 | 
					@ -204,29 +204,6 @@ struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root,
 | 
				
			||||||
	return re;
 | 
						return re;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct rb_node **f2fs_lookup_rb_tree_ext(struct f2fs_sb_info *sbi,
 | 
					 | 
				
			||||||
					struct rb_root_cached *root,
 | 
					 | 
				
			||||||
					struct rb_node **parent,
 | 
					 | 
				
			||||||
					unsigned long long key, bool *leftmost)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct rb_node **p = &root->rb_root.rb_node;
 | 
					 | 
				
			||||||
	struct rb_entry *re;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	while (*p) {
 | 
					 | 
				
			||||||
		*parent = *p;
 | 
					 | 
				
			||||||
		re = rb_entry(*parent, struct rb_entry, rb_node);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (key < re->key) {
 | 
					 | 
				
			||||||
			p = &(*p)->rb_left;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			p = &(*p)->rb_right;
 | 
					 | 
				
			||||||
			*leftmost = false;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return p;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
 | 
					struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
 | 
				
			||||||
				struct rb_root_cached *root,
 | 
									struct rb_root_cached *root,
 | 
				
			||||||
				struct rb_node **parent,
 | 
									struct rb_node **parent,
 | 
				
			||||||
| 
						 | 
					@ -335,7 +312,7 @@ struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root_cached *root,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi,
 | 
					bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi,
 | 
				
			||||||
				struct rb_root_cached *root, bool check_key)
 | 
									struct rb_root_cached *root)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef CONFIG_F2FS_CHECK_FS
 | 
					#ifdef CONFIG_F2FS_CHECK_FS
 | 
				
			||||||
	struct rb_node *cur = rb_first_cached(root), *next;
 | 
						struct rb_node *cur = rb_first_cached(root), *next;
 | 
				
			||||||
| 
						 | 
					@ -352,23 +329,12 @@ bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi,
 | 
				
			||||||
		cur_re = rb_entry(cur, struct rb_entry, rb_node);
 | 
							cur_re = rb_entry(cur, struct rb_entry, rb_node);
 | 
				
			||||||
		next_re = rb_entry(next, struct rb_entry, rb_node);
 | 
							next_re = rb_entry(next, struct rb_entry, rb_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_key) {
 | 
					 | 
				
			||||||
			if (cur_re->key > next_re->key) {
 | 
					 | 
				
			||||||
				f2fs_info(sbi, "inconsistent rbtree, "
 | 
					 | 
				
			||||||
					"cur(%llu) next(%llu)",
 | 
					 | 
				
			||||||
					cur_re->key, next_re->key);
 | 
					 | 
				
			||||||
				return false;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			goto next;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (cur_re->ofs + cur_re->len > next_re->ofs) {
 | 
							if (cur_re->ofs + cur_re->len > next_re->ofs) {
 | 
				
			||||||
			f2fs_info(sbi, "inconsistent rbtree, cur(%u, %u) next(%u, %u)",
 | 
								f2fs_info(sbi, "inconsistent rbtree, cur(%u, %u) next(%u, %u)",
 | 
				
			||||||
				  cur_re->ofs, cur_re->len,
 | 
									  cur_re->ofs, cur_re->len,
 | 
				
			||||||
				  next_re->ofs, next_re->len);
 | 
									  next_re->ofs, next_re->len);
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
next:
 | 
					 | 
				
			||||||
		cur = next;
 | 
							cur = next;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -630,13 +630,8 @@ enum extent_type {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct rb_entry {
 | 
					struct rb_entry {
 | 
				
			||||||
	struct rb_node rb_node;		/* rb node located in rb-tree */
 | 
						struct rb_node rb_node;		/* rb node located in rb-tree */
 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct {
 | 
					 | 
				
			||||||
	unsigned int ofs;		/* start offset of the entry */
 | 
						unsigned int ofs;		/* start offset of the entry */
 | 
				
			||||||
	unsigned int len;		/* length of the entry */
 | 
						unsigned int len;		/* length of the entry */
 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		unsigned long long key;		/* 64-bits key */
 | 
					 | 
				
			||||||
	} __packed;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct extent_info {
 | 
					struct extent_info {
 | 
				
			||||||
| 
						 | 
					@ -4139,10 +4134,6 @@ void f2fs_leave_shrinker(struct f2fs_sb_info *sbi);
 | 
				
			||||||
bool sanity_check_extent_cache(struct inode *inode);
 | 
					bool sanity_check_extent_cache(struct inode *inode);
 | 
				
			||||||
struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root,
 | 
					struct rb_entry *f2fs_lookup_rb_tree(struct rb_root_cached *root,
 | 
				
			||||||
				struct rb_entry *cached_re, unsigned int ofs);
 | 
									struct rb_entry *cached_re, unsigned int ofs);
 | 
				
			||||||
struct rb_node **f2fs_lookup_rb_tree_ext(struct f2fs_sb_info *sbi,
 | 
					 | 
				
			||||||
				struct rb_root_cached *root,
 | 
					 | 
				
			||||||
				struct rb_node **parent,
 | 
					 | 
				
			||||||
				unsigned long long key, bool *left_most);
 | 
					 | 
				
			||||||
struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
 | 
					struct rb_node **f2fs_lookup_rb_tree_for_insert(struct f2fs_sb_info *sbi,
 | 
				
			||||||
				struct rb_root_cached *root,
 | 
									struct rb_root_cached *root,
 | 
				
			||||||
				struct rb_node **parent,
 | 
									struct rb_node **parent,
 | 
				
			||||||
| 
						 | 
					@ -4153,7 +4144,7 @@ struct rb_entry *f2fs_lookup_rb_tree_ret(struct rb_root_cached *root,
 | 
				
			||||||
		struct rb_node ***insert_p, struct rb_node **insert_parent,
 | 
							struct rb_node ***insert_p, struct rb_node **insert_parent,
 | 
				
			||||||
		bool force, bool *leftmost);
 | 
							bool force, bool *leftmost);
 | 
				
			||||||
bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi,
 | 
					bool f2fs_check_rb_tree_consistence(struct f2fs_sb_info *sbi,
 | 
				
			||||||
				struct rb_root_cached *root, bool check_key);
 | 
									struct rb_root_cached *root);
 | 
				
			||||||
void f2fs_init_extent_tree(struct inode *inode);
 | 
					void f2fs_init_extent_tree(struct inode *inode);
 | 
				
			||||||
void f2fs_drop_extent_tree(struct inode *inode);
 | 
					void f2fs_drop_extent_tree(struct inode *inode);
 | 
				
			||||||
void f2fs_destroy_extent_node(struct inode *inode);
 | 
					void f2fs_destroy_extent_node(struct inode *inode);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										139
									
								
								fs/f2fs/gc.c
									
									
									
									
									
								
							
							
						
						
									
										139
									
								
								fs/f2fs/gc.c
									
									
									
									
									
								
							| 
						 | 
					@ -390,40 +390,95 @@ static unsigned int count_bits(const unsigned long *addr,
 | 
				
			||||||
	return sum;
 | 
						return sum;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct victim_entry *attach_victim_entry(struct f2fs_sb_info *sbi,
 | 
					static bool f2fs_check_victim_tree(struct f2fs_sb_info *sbi,
 | 
				
			||||||
				unsigned long long mtime, unsigned int segno,
 | 
									struct rb_root_cached *root)
 | 
				
			||||||
				struct rb_node *parent, struct rb_node **p,
 | 
					{
 | 
				
			||||||
				bool left_most)
 | 
					#ifdef CONFIG_F2FS_CHECK_FS
 | 
				
			||||||
 | 
						struct rb_node *cur = rb_first_cached(root), *next;
 | 
				
			||||||
 | 
						struct victim_entry *cur_ve, *next_ve;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (cur) {
 | 
				
			||||||
 | 
							next = rb_next(cur);
 | 
				
			||||||
 | 
							if (!next)
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							cur_ve = rb_entry(cur, struct victim_entry, rb_node);
 | 
				
			||||||
 | 
							next_ve = rb_entry(next, struct victim_entry, rb_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (cur_ve->mtime > next_ve->mtime) {
 | 
				
			||||||
 | 
								f2fs_info(sbi, "broken victim_rbtree, "
 | 
				
			||||||
 | 
									"cur_mtime(%llu) next_mtime(%llu)",
 | 
				
			||||||
 | 
									cur_ve->mtime, next_ve->mtime);
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							cur = next;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct victim_entry *__lookup_victim_entry(struct f2fs_sb_info *sbi,
 | 
				
			||||||
 | 
										unsigned long long mtime)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct atgc_management *am = &sbi->am;
 | 
				
			||||||
 | 
						struct rb_node *node = am->root.rb_root.rb_node;
 | 
				
			||||||
 | 
						struct victim_entry *ve = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						while (node) {
 | 
				
			||||||
 | 
							ve = rb_entry(node, struct victim_entry, rb_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (mtime < ve->mtime)
 | 
				
			||||||
 | 
								node = node->rb_left;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								node = node->rb_right;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ve;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct victim_entry *__create_victim_entry(struct f2fs_sb_info *sbi,
 | 
				
			||||||
 | 
							unsigned long long mtime, unsigned int segno)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atgc_management *am = &sbi->am;
 | 
						struct atgc_management *am = &sbi->am;
 | 
				
			||||||
	struct victim_entry *ve;
 | 
						struct victim_entry *ve;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ve =  f2fs_kmem_cache_alloc(victim_entry_slab,
 | 
						ve =  f2fs_kmem_cache_alloc(victim_entry_slab, GFP_NOFS, true, NULL);
 | 
				
			||||||
				GFP_NOFS, true, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ve->mtime = mtime;
 | 
						ve->mtime = mtime;
 | 
				
			||||||
	ve->segno = segno;
 | 
						ve->segno = segno;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rb_link_node(&ve->rb_node, parent, p);
 | 
					 | 
				
			||||||
	rb_insert_color_cached(&ve->rb_node, &am->root, left_most);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	list_add_tail(&ve->list, &am->victim_list);
 | 
						list_add_tail(&ve->list, &am->victim_list);
 | 
				
			||||||
 | 
					 | 
				
			||||||
	am->victim_count++;
 | 
						am->victim_count++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ve;
 | 
						return ve;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void insert_victim_entry(struct f2fs_sb_info *sbi,
 | 
					static void __insert_victim_entry(struct f2fs_sb_info *sbi,
 | 
				
			||||||
				unsigned long long mtime, unsigned int segno)
 | 
									unsigned long long mtime, unsigned int segno)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atgc_management *am = &sbi->am;
 | 
						struct atgc_management *am = &sbi->am;
 | 
				
			||||||
	struct rb_node **p;
 | 
						struct rb_root_cached *root = &am->root;
 | 
				
			||||||
 | 
						struct rb_node **p = &root->rb_root.rb_node;
 | 
				
			||||||
	struct rb_node *parent = NULL;
 | 
						struct rb_node *parent = NULL;
 | 
				
			||||||
 | 
						struct victim_entry *ve;
 | 
				
			||||||
	bool left_most = true;
 | 
						bool left_most = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p = f2fs_lookup_rb_tree_ext(sbi, &am->root, &parent, mtime, &left_most);
 | 
						/* look up rb tree to find parent node */
 | 
				
			||||||
	attach_victim_entry(sbi, mtime, segno, parent, p, left_most);
 | 
						while (*p) {
 | 
				
			||||||
 | 
							parent = *p;
 | 
				
			||||||
 | 
							ve = rb_entry(parent, struct victim_entry, rb_node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (mtime < ve->mtime) {
 | 
				
			||||||
 | 
								p = &(*p)->rb_left;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								p = &(*p)->rb_right;
 | 
				
			||||||
 | 
								left_most = false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ve = __create_victim_entry(sbi, mtime, segno);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rb_link_node(&ve->rb_node, parent, p);
 | 
				
			||||||
 | 
						rb_insert_color_cached(&ve->rb_node, root, left_most);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void add_victim_entry(struct f2fs_sb_info *sbi,
 | 
					static void add_victim_entry(struct f2fs_sb_info *sbi,
 | 
				
			||||||
| 
						 | 
					@ -459,19 +514,7 @@ static void add_victim_entry(struct f2fs_sb_info *sbi,
 | 
				
			||||||
	if (sit_i->dirty_max_mtime - mtime < p->age_threshold)
 | 
						if (sit_i->dirty_max_mtime - mtime < p->age_threshold)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	insert_victim_entry(sbi, mtime, segno);
 | 
						__insert_victim_entry(sbi, mtime, segno);
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct rb_node *lookup_central_victim(struct f2fs_sb_info *sbi,
 | 
					 | 
				
			||||||
						struct victim_sel_policy *p)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct atgc_management *am = &sbi->am;
 | 
					 | 
				
			||||||
	struct rb_node *parent = NULL;
 | 
					 | 
				
			||||||
	bool left_most;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f2fs_lookup_rb_tree_ext(sbi, &am->root, &parent, p->age, &left_most);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return parent;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void atgc_lookup_victim(struct f2fs_sb_info *sbi,
 | 
					static void atgc_lookup_victim(struct f2fs_sb_info *sbi,
 | 
				
			||||||
| 
						 | 
					@ -481,7 +524,6 @@ static void atgc_lookup_victim(struct f2fs_sb_info *sbi,
 | 
				
			||||||
	struct atgc_management *am = &sbi->am;
 | 
						struct atgc_management *am = &sbi->am;
 | 
				
			||||||
	struct rb_root_cached *root = &am->root;
 | 
						struct rb_root_cached *root = &am->root;
 | 
				
			||||||
	struct rb_node *node;
 | 
						struct rb_node *node;
 | 
				
			||||||
	struct rb_entry *re;
 | 
					 | 
				
			||||||
	struct victim_entry *ve;
 | 
						struct victim_entry *ve;
 | 
				
			||||||
	unsigned long long total_time;
 | 
						unsigned long long total_time;
 | 
				
			||||||
	unsigned long long age, u, accu;
 | 
						unsigned long long age, u, accu;
 | 
				
			||||||
| 
						 | 
					@ -508,12 +550,10 @@ static void atgc_lookup_victim(struct f2fs_sb_info *sbi,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	node = rb_first_cached(root);
 | 
						node = rb_first_cached(root);
 | 
				
			||||||
next:
 | 
					next:
 | 
				
			||||||
	re = rb_entry_safe(node, struct rb_entry, rb_node);
 | 
						ve = rb_entry_safe(node, struct victim_entry, rb_node);
 | 
				
			||||||
	if (!re)
 | 
						if (!ve)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ve = (struct victim_entry *)re;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ve->mtime >= max_mtime || ve->mtime < min_mtime)
 | 
						if (ve->mtime >= max_mtime || ve->mtime < min_mtime)
 | 
				
			||||||
		goto skip;
 | 
							goto skip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -555,8 +595,6 @@ static void atssr_lookup_victim(struct f2fs_sb_info *sbi,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sit_info *sit_i = SIT_I(sbi);
 | 
						struct sit_info *sit_i = SIT_I(sbi);
 | 
				
			||||||
	struct atgc_management *am = &sbi->am;
 | 
						struct atgc_management *am = &sbi->am;
 | 
				
			||||||
	struct rb_node *node;
 | 
					 | 
				
			||||||
	struct rb_entry *re;
 | 
					 | 
				
			||||||
	struct victim_entry *ve;
 | 
						struct victim_entry *ve;
 | 
				
			||||||
	unsigned long long age;
 | 
						unsigned long long age;
 | 
				
			||||||
	unsigned long long max_mtime = sit_i->dirty_max_mtime;
 | 
						unsigned long long max_mtime = sit_i->dirty_max_mtime;
 | 
				
			||||||
| 
						 | 
					@ -566,25 +604,22 @@ static void atssr_lookup_victim(struct f2fs_sb_info *sbi,
 | 
				
			||||||
	unsigned int dirty_threshold = max(am->max_candidate_count,
 | 
						unsigned int dirty_threshold = max(am->max_candidate_count,
 | 
				
			||||||
					am->candidate_ratio *
 | 
										am->candidate_ratio *
 | 
				
			||||||
					am->victim_count / 100);
 | 
										am->victim_count / 100);
 | 
				
			||||||
	unsigned int cost;
 | 
						unsigned int cost, iter;
 | 
				
			||||||
	unsigned int iter = 0;
 | 
					 | 
				
			||||||
	int stage = 0;
 | 
						int stage = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (max_mtime < min_mtime)
 | 
						if (max_mtime < min_mtime)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	max_mtime += 1;
 | 
						max_mtime += 1;
 | 
				
			||||||
next_stage:
 | 
					next_stage:
 | 
				
			||||||
	node = lookup_central_victim(sbi, p);
 | 
						iter = 0;
 | 
				
			||||||
 | 
						ve = __lookup_victim_entry(sbi, p->age);
 | 
				
			||||||
next_node:
 | 
					next_node:
 | 
				
			||||||
	re = rb_entry_safe(node, struct rb_entry, rb_node);
 | 
						if (!ve) {
 | 
				
			||||||
	if (!re) {
 | 
							if (stage++ == 0)
 | 
				
			||||||
		if (stage == 0)
 | 
								goto next_stage;
 | 
				
			||||||
			goto skip_stage;
 | 
					 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ve = (struct victim_entry *)re;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (ve->mtime >= max_mtime || ve->mtime < min_mtime)
 | 
						if (ve->mtime >= max_mtime || ve->mtime < min_mtime)
 | 
				
			||||||
		goto skip_node;
 | 
							goto skip_node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -610,24 +645,20 @@ static void atssr_lookup_victim(struct f2fs_sb_info *sbi,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
skip_node:
 | 
					skip_node:
 | 
				
			||||||
	if (iter < dirty_threshold) {
 | 
						if (iter < dirty_threshold) {
 | 
				
			||||||
		if (stage == 0)
 | 
							ve = rb_entry(stage == 0 ? rb_prev(&ve->rb_node) :
 | 
				
			||||||
			node = rb_prev(node);
 | 
										rb_next(&ve->rb_node),
 | 
				
			||||||
		else if (stage == 1)
 | 
										struct victim_entry, rb_node);
 | 
				
			||||||
			node = rb_next(node);
 | 
					 | 
				
			||||||
		goto next_node;
 | 
							goto next_node;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
skip_stage:
 | 
					
 | 
				
			||||||
	if (stage < 1) {
 | 
						if (stage++ == 0)
 | 
				
			||||||
		stage++;
 | 
					 | 
				
			||||||
		iter = 0;
 | 
					 | 
				
			||||||
		goto next_stage;
 | 
							goto next_stage;
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void lookup_victim_by_age(struct f2fs_sb_info *sbi,
 | 
					static void lookup_victim_by_age(struct f2fs_sb_info *sbi,
 | 
				
			||||||
						struct victim_sel_policy *p)
 | 
											struct victim_sel_policy *p)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi,
 | 
						f2fs_bug_on(sbi, !f2fs_check_victim_tree(sbi, &sbi->am.root));
 | 
				
			||||||
						&sbi->am.root, true));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (p->gc_mode == GC_AT)
 | 
						if (p->gc_mode == GC_AT)
 | 
				
			||||||
		atgc_lookup_victim(sbi, p);
 | 
							atgc_lookup_victim(sbi, p);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										10
									
								
								fs/f2fs/gc.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								fs/f2fs/gc.h
									
									
									
									
									
								
							| 
						 | 
					@ -55,20 +55,10 @@ struct gc_inode_list {
 | 
				
			||||||
	struct radix_tree_root iroot;
 | 
						struct radix_tree_root iroot;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct victim_info {
 | 
					 | 
				
			||||||
	unsigned long long mtime;	/* mtime of section */
 | 
					 | 
				
			||||||
	unsigned int segno;		/* section No. */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct victim_entry {
 | 
					struct victim_entry {
 | 
				
			||||||
	struct rb_node rb_node;		/* rb node located in rb-tree */
 | 
						struct rb_node rb_node;		/* rb node located in rb-tree */
 | 
				
			||||||
	union {
 | 
					 | 
				
			||||||
		struct {
 | 
					 | 
				
			||||||
	unsigned long long mtime;	/* mtime of section */
 | 
						unsigned long long mtime;	/* mtime of section */
 | 
				
			||||||
	unsigned int segno;		/* segment No. */
 | 
						unsigned int segno;		/* segment No. */
 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		struct victim_info vi;	/* victim info */
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	struct list_head list;
 | 
						struct list_head list;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1478,7 +1478,7 @@ static int __issue_discard_cmd(struct f2fs_sb_info *sbi,
 | 
				
			||||||
			goto next;
 | 
								goto next;
 | 
				
			||||||
		if (unlikely(dcc->rbtree_check))
 | 
							if (unlikely(dcc->rbtree_check))
 | 
				
			||||||
			f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi,
 | 
								f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi,
 | 
				
			||||||
							&dcc->root, false));
 | 
												&dcc->root));
 | 
				
			||||||
		blk_start_plug(&plug);
 | 
							blk_start_plug(&plug);
 | 
				
			||||||
		list_for_each_entry_safe(dc, tmp, pend_list, list) {
 | 
							list_for_each_entry_safe(dc, tmp, pend_list, list) {
 | 
				
			||||||
			f2fs_bug_on(sbi, dc->state != D_PREP);
 | 
								f2fs_bug_on(sbi, dc->state != D_PREP);
 | 
				
			||||||
| 
						 | 
					@ -2965,7 +2965,7 @@ static unsigned int __issue_discard_cmd_range(struct f2fs_sb_info *sbi,
 | 
				
			||||||
	mutex_lock(&dcc->cmd_lock);
 | 
						mutex_lock(&dcc->cmd_lock);
 | 
				
			||||||
	if (unlikely(dcc->rbtree_check))
 | 
						if (unlikely(dcc->rbtree_check))
 | 
				
			||||||
		f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi,
 | 
							f2fs_bug_on(sbi, !f2fs_check_rb_tree_consistence(sbi,
 | 
				
			||||||
							&dcc->root, false));
 | 
												&dcc->root));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dc = (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root,
 | 
						dc = (struct discard_cmd *)f2fs_lookup_rb_tree_ret(&dcc->root,
 | 
				
			||||||
					NULL, start,
 | 
										NULL, start,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue