zfs是有两个缓冲区的。首先是dmu buffer,如果dmu buffer中没有数据再找arc buffer,如果找到了,那么就直接调用回调函数,将arc buffer的内容传给dmu buffer。如果再找不到就找磁盘。
具体的实现细节如下:
dbuf_read 首先会看 dmu buffer的状态,如果是UNCACHED。
就会调用 dbuf_read_impl函数。
dbuf_read_impl函数会调用dsl_read,进而从arcbuffer中找数据。找的方法是根据db的db_blkptr来查找。
- (void) dsl_read(zio, spa, db->db_blkptr, pbuf,
- dbuf_read_done, db, ZIO_PRIORITY_SYNC_READ,
- (*flags & DB_RF_CANFAIL) ? ZIO_FLAG_CANFAIL : ZIO_FLAG_MUSTSUCCEED,
- &aflags, &zb);
然后调用arc_read函数,从arcbuffer中找。
真正的函数在这里可以看到 buf_hash_find根据blkptr,来映射到hash表中,经过hash查找,结果返回hdr。
- hdr = buf_hash_find(guid, BP_IDENTITY(bp), BP_PHYSICAL_BIRTH(bp),
- &hash_lock);
如果找到了,hdr->buf中含有的db想要的数据,说明arc buffer命中。然后调用回调函数返回。如果没找到,那么就向磁盘发请求。
这种双buffer的设计不得不让zfs在写的时候也得考虑arc buffer,也就是在同步dmu buffer的时候,sync_leaf函数会调用arc_write函数,在这个函数当中会给zio设置回调函数,在回调函数当中,将zio的数据传送到arc buffer上(插入算法为HASH算法)。
阅读(1599) | 评论(0) | 转发(0) |