当写buffer的操作完成之后,在dbuf_dirty函数当中,会创建一个dr,dr所属的txg 为 open txg 的 txg id。
然后 他会插入到dnode的dn_dirty_records当中。
为了以后同步的时候使用,所以 根据txgoff=txg & TXG_MASK,算出相应的txgoff,然后插入进去。
当open txg 变成 sync txg的时候,sync thread会调用函数spa_sync ,大范围内的进行同步操作。
spa_sync(spa,txg)
- list_insert_tail(&dn->dn_dirty_records[txgoff], dr);
向下同步的时候,他会从dn->dn_dirty_records[txgoff]当中,同步之前插入的脏记录。
简单的事例代码如下:
- list = dn->dn_dirty_records[txgoff];
- dbuf_sync_list(list, tx);
完成了dbuf_sync_leaf 操作,zfs会记录这次写磁盘的块的blk_birth 为txg。相当于块的创建时间,然后执行zio_nowait(zio),异步的将脏记录写入到磁盘上了。
这样就完成了一次写操作。但是我的分析是高度概括的,很多的实现细节由于篇幅有限没法完全说清楚,有机会再逐渐的补充吧。
阅读(2081) | 评论(0) | 转发(0) |