F2FS重要数据结构详解之struct dirty_seglist_info

F2FS重要数据结构详解之struct dirty_seglist_info

struct f2fs_sm_info 是f2fs的重要数据结构之一,维护了 segment 在内存中的元数据信息,关于许多博客已经介绍,这里不多赘述,这里主要介绍struct f2fs_sm_info内部的另一个重要数据结构struct f2fs_sm_info

struct f2fs_sm_info {struct dirty_seglist_info *dirty_info;        /* dirty segment information */};

数据结构分析

struct f2fs_sm_info 主要维护了文件系统的脏segment信息,包括 dirty 和 prefree,具体数据结构如下:

struct dirty_seglist_info {
    const struct victim_selection *v_ops;        /* victim selction operation */
    unsigned long *dirty_segmap[NR_DIRTY_TYPE];
    struct mutex seglist_lock;                /* lock for segment bitmaps */
    int nr_dirty[NR_DIRTY_TYPE];                /* # of dirty segments */
    unsigned long *victim_secmap;                /* background GC victims */
};
1. 第一个成员记录了选择 victim 的策略,即一个回调函数,用于选择 victim
	/* victim selection function for cleaning and SSR */
	struct victim_selection {
	    int (*get_victim)(struct f2fs_sb_info *, unsigned int *, int, int, char);
	}
	
2. 第二个成员维护了 NR_DIRTY_TYPE(8)张位图
	/* Notice: The order of dirty type is same with CURSEG_XXX in f2fs.h */
	enum dirty_type {
	    DIRTY_HOT_DATA,                /* dirty segments assigned as hot data logs */
	    DIRTY_WARM_DATA,        /* dirty segments assigned as warm data logs */
	    DIRTY_COLD_DATA,        /* dirty segments assigned as cold data logs */
	    DIRTY_HOT_NODE,                /* dirty segments assigned as hot node logs */
	    DIRTY_WARM_NODE,        /* dirty segments assigned as warm node logs */
	    DIRTY_COLD_NODE,        /* dirty segments assigned as cold node logs */
	    DIRTY,                        /* to count # of dirty segments */
	    PRE,                        /* to count # of entirely obsolete segments */
	    NR_DIRTY_TYPE
	};
3. 第四个成员记录了8种 dirty segment 的数量

相关函数分析

1 	/*
2 	 * Should not occur error such as -ENOMEM.
3 	 * Adding dirty entry into seglist is not critical operation.
4 	 * If a given segment is one of current working segments, it won't be added.
5 	 *
6 	 *        如果这个seg中有效block数等于0,把这个segment归为prefree,在prefree位图上将segno的位置置位
7 	 *                然后在dirty位图上将segno的位置取消置位
8 	 *        如果这个seg中有效block数等于512,把这个segment归为valid,在dirty位图上将segno的位置取消置位
9 	 *        如果这个seg中有效block数介于0~512之间,把这个segment归为dirty,在dirty位图上将segno的位置置位
10 	 *
11 	 *        所以总的来说,这个函数的目的是分情况将segment置脏
12 	 */
13 	static void locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno)
14 	{
15 	        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
16 	        unsigned short valid_blocks;
17 	        
18 	        if (segno == NULL_SEGNO || IS_CURSEG(sbi, segno))
19 	                return;
20 	        
21 	        mutex_lock(&dirty_i->seglist_lock);
22 	        
23 	        valid_blocks = get_valid_blocks(sbi, segno, 0);
24 	        
25 	        if (valid_blocks == 0) {
26 	                __locate_dirty_segment(sbi, segno, PRE);
27 	                __remove_dirty_segment(sbi, segno, DIRTY);
28 	                } else if (valid_blocks < sbi->blocks_per_seg) {
29 	                __locate_dirty_segment(sbi, segno, DIRTY);
30 	                } else {
31 	                /* Recovery routine with SSR needs this */
32 	                __remove_dirty_segment(sbi, segno, DIRTY);
33 	        }
34 	        
35 	        mutex_unlock(&dirty_i->seglist_lock);
36 	}
37 	
38 	
39 	// dirty_seglist_info 维护的位图中,将dirty_type类型的位图上将segno对应的位置置位 
40 	static void __locate_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno, enum dirty_type dirty_type)
41 	{
42 	        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
43 	        
44 	        /* need not be added */
45 	        if (IS_CURSEG(sbi, segno))
46 	                return;
47 	        
48 	        if (!test_and_set_bit(segno, dirty_i->dirty_segmap[dirty_type]))
49 	                dirty_i->nr_dirty[dirty_type]++;
50 	        
51 	        if (dirty_type == DIRTY) {
52 	                struct seg_entry *sentry = get_seg_entry(sbi, segno);
53 	                enum dirty_type t = sentry->type;
54 	        
55 	                if (unlikely(t >= DIRTY)) {
56 	                        f2fs_bug_on(sbi, 1);
57 	                        return;
58 	                }
59 	                if (!test_and_set_bit(segno, dirty_i->dirty_segmap[t]))
60 	                        dirty_i->nr_dirty[t]++;
61 	        }
62 	}
63 	
64 	// dirty_seglist_info 维护的位图中,将dirty_type类型的位图上将segno对应的位置取消置位 
65 	static void __remove_dirty_segment(struct f2fs_sb_info *sbi, unsigned int segno, enum dirty_type dirty_type)
66 	{
67 	        struct dirty_seglist_info *dirty_i = DIRTY_I(sbi);
68 	        
69 	        if (test_and_clear_bit(segno, dirty_i->dirty_segmap[dirty_type]))
70 	                dirty_i->nr_dirty[dirty_type]--;
71 	        
72 	        if (dirty_type == DIRTY) {
73 	                struct seg_entry *sentry = get_seg_entry(sbi, segno);
74 	                enum dirty_type t = sentry->type;
75 	        
76 	                if (test_and_clear_bit(segno, dirty_i->dirty_segmap[t]))
77 	                        dirty_i->nr_dirty[t]--;
78 	        
79 	                if (get_valid_blocks(sbi, segno, sbi->segs_per_sec) == 0)
80 	                        clear_bit(GET_SECNO(sbi, segno),
81 	                dirty_i->victim_secmap);
82 	        }
83 	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值