f2fs解析(七)node管理器中的 free_nid 结构体

除了node_info之外, node管理器中还有还有个重要的数据结构:

145 struct free_nid {
146     struct list_head list;  /* for free node id list */
147     nid_t nid;      /* node id */
148     int state;      /* in use or not: NID_NEW or NID_ALLOC */
149 };       

这个结构体体很简单,比刚才的node_info轻量级多了,仅仅是标识了当前可以使用的nid,以及这个nid的状态,一个指针将其与别的free_nid连成一串。

别看这个结构简单,也被node管理器中两个 “索引” 管理着呢:1)基数树 free_nid_root; 2)链表 free_nid_list;【参见函数add_free_nid】

但是咱这个free_nid 也总得有个出栈的时候吧,你得为国家建设做贡献,不然在占个位置干嘛呢!

alloc_nid 函数会从 free_nid_list 链表中选出一个free_nid出来,这个nid算是被选中了,但是此时并不会把这个节点从list删除,为什么呢?因为选中nid只是万里长征的第一步,后面还有许多事情要做呢,这些事情没做完我们就不能删除,如果中途失败,那么咱这个nid算是分配出去了,到哪儿找呢!所以要给自己回旋的余地啊,f2fs的代码巧妙地把此时free_nid的状态从NID_NEW变成了NID_ALLOC,什么时候完全从链表中删除呢?

函数:alloc_nid_done ! 其中,狠心的__del_from_free_nid_list,会将这个节点从链表中删除,并删除基数树中的索引。然后其在slab中的位置也被释放了!

1634 /*
1635  * alloc_nid() should be called prior to this function.
1636  */
1637 void alloc_nid_done(struct f2fs_sb_info *sbi, nid_t nid)
1638 {
1643     i = __lookup_free_nid_list(nm_i, nid); //从基数树中删除这个节点
1644     f2fs_bug_on(sbi, !i || i->state != NID_ALLOC);
1645     __del_from_free_nid_list(nm_i, i); //从链表中删除..
1648     kmem_cache_free(free_nid_slab, i);
1649 }
1650 

 

1451 static void __del_from_free_nid_list(struct f2fs_nm_info *nm_i,
1452                         struct free_nid *i)
1453 {
1454     list_del(&i->list);
1455     radix_tree_delete(&nm_i->free_nid_root, i->nid);
1456 }
1

到这里我们基本了解了free_nid的一生。并且也基本猜到了他的一个作用:为node_info的出场暖场呢!

posted @ 2015-11-07 21:57  honpey  阅读(1180)  评论(0编辑  收藏  举报