• f2fs解析(十)nid 如何从nat_root中删除


    上面我们谈到了一个nid如何从free_nid中转移到node_info中去【分别有一个链表和一棵基数树搭伙做事】,讲free_nid时,详细说明了free_nid中是如何进如何出的,上一篇说了nid是如何进入nat_root的,当然一个nid进入nat_root的情况不止如此呢,还包括如果读磁盘中已经存在的一个nid,这个nid的缓存也是存在这里的。

    那么现在说说nat_root中的nid是如何刷回去的!

    涉及一个函数:__del_from_nat_cache

    两个地方调用:
    1)f2fs_balance_fs_bg --> try_to_free_nats --> __del_from_nat_cache 【内存紧张的时候,直接丢弃】

    2)destroy_node_manager --> __del_from_nat_cache 【写checkpoint】

    对于第一种情况,有个疑问:如果这个nat_entry并没有写回磁盘那怎么办?!

    这个情况不会发生的,你会发现在函数 f2fs_write_node_page 中当nat中设置一个新地址时,会调用_set_nat_cache_dirty,将其从本来待的nat_entries链表中删除,然后放入nat_set_root中这个block对应的那个list链表中去。是不是很拗口?

    解释一下:nat_set_root是我们今天要看的第三棵基数树了,也是最后的一棵树了,杀千刀的node管理器终于要见底了,这里是一个nid的最后归宿啦!nat_set_root是棵什么树呢?这棵基数树的索引是这个nat_entry所在的nat块,这个块中所有的所有的nat_entry都链到在他的entry_list中的!都是脏的块哇!有没有!

    130 struct nat_entry_set {
    131     struct list_head set_list;  /* link with other nat sets */
    132     struct list_head entry_list;    /* link with dirty nat entries */
    133     nid_t set;          /* set number*/
    134     unsigned int entry_cnt;     /* the # of nat entries in set */
    135 };   
    136 

    上面标蓝的第一条线,在丢弃这些cache之前,要用段管理器中的锁的:nat_tree_lock。 down_write(&nm_i->nat_tree_lock) 和 up_write(&nm_i->nat_tree_lock) 要套起来,set_node_addr中也要有这个锁啊,果然,这个函数一上来,这个锁就套上了!

    至此,我们知道了nid去哪儿了!原来,nat_root,只是nid暂时的一站,真的是暂时的一站,立马,你就去了就到了nat_set_root中自己的那个nat_entry_set中去了!

    好了,就这样了!nat_entry_set中的东西到write_checkpoint的时候清除了!

     down_write(&nm_i->nat_tree_lock);

  • 相关阅读:
    康复计划#4 快速构造支配树的Lengauer-Tarjan算法
    康复计划#3 简单常用的几种计算自然数幂和的方法
    长链剖分随想
    康复计划#2 常用基础数论知识杂烩
    康复计划#1 再探后缀自动机&后缀树
    WC2017游记 & 能力残废康复计划
    Bubble Cup 8 finals I. Robots protection (575I)
    Bubble Cup 8 finals H. Bots (575H)
    Angular懒加载模块使用http拦截失效问题
    Git Commit提交规范
  • 原文地址:https://www.cnblogs.com/honpey/p/4946417.html
Copyright © 2020-2023  润新知