zoukankan      html  css  js  c++  java
  • 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);

  • 相关阅读:
    阶梯电价、提成、个税计算公式思路解析
    Java单元测试(Junit+Mock+代码覆盖率)
    Spring Cache抽象详解
    关于String 后面跟省略号。。。
    centOS上安装redis
    使用 JMeter 完成常用的压力测试
    调用 jdbcTemplate.queryForList 时出现错误 spring-org.springframework.jdbc.IncorrectResultSetColumnCountException
    C/C++log日志库比较
    QT中使用MinGW 编译的protobuf库--包含库的生成和使用
    win10 下 protobuf 与 qt
  • 原文地址:https://www.cnblogs.com/honpey/p/4946417.html
Copyright © 2011-2022 走看看