仍然以DFTL为例,在 dftl.c
文件中有一个 opm_write()
函数,前面对这个函数也进行过介绍,这个函数主要是实现 dftl 的写操作逻辑。在这个函数中会进行 GC 操作的判断,先调用 nand_get_free_blk(0)
函数,如果返回 -1 ,则表示需要进行垃圾回收,当整个 SSD 的空闲页大于阈值的时候就停止垃圾回收。这部分的代码,如下所示:
1 | if (free_page_no[small] >= SECT_NUM_PER_BLK){ //当前正在写的 block 已经写完了 |
在 dflt.c 中,进行GC的操作是在 opm_gc_run() 函数中进行的。GC 操作大致分为以下几个步骤:
- 选择无效数据最少的 block 进行回收。
- 迁移 block 中的有效数据,并同时更新映射表。
- 对于被迁移的数据的映射记录没有在缓冲区命中时,需要进行映射表的读写,也就是说需要额外增加两次IO。
注意:在垃圾回收时,如果迁移数据对应的映射记录没有在缓冲区命中,会从闪存中把映射表读入到缓存,更改后又写会闪存,不会放入缓冲区内。
下面具体介绍 opm_gc_run()
函数:
1 | int opm_gc_run(int small, int mapdir_flag){ |