bitmap原理很明了,按照这个原理直接进行实施也是可以的,但直接这样实施的话,由于一次数据块的写入多了两次磁盘访问(bitmap的设置和清除),写入效率会受到较大影响,所以还需要考虑一些优化。
优化主要是两方面的:bitmap的设置后批量写入;bitmap的延时清除。这两方面的优化原理上和磁盘缓存差不多,需要在内存中构建和磁盘bitmap文件对应的数据结构,bitmap操作首先在缓存中进行,必要时才进行真正的磁盘操作。
下面来看看bitmap在磁盘上以及在内存中的结构。
Bitmap文件的磁盘组织
Bitmap磁盘文件可以存放在MD设备之外,此时MD结构中的bitmap_file表示这个bitmap文件;bitmap磁盘文件也可以存放在MD设备自身,这个bitmap相对于MD的超级块的位置由bitmap_offset指定(注意这个值也可以为负,表示Bitmap文件存放在超级块之前)。
磁盘文件由超级块和位图组成,超级块大小为256字节,随后紧跟位图。位图中,一个位对应磁阵中一段条带段,这个大小由超级块的chunksize字段确定,位被设置则表示该对应chunk需要同步,位被清零表示对应chunk状态一致,无需同步。
超级块
typedef struct bitmap_super_s {
__le32 magic; /* 0 BITMAP_MAGIC */
__le32 version; /* 4 the bitmap major for now, could change... */
__u8 uuid[16]; /* 8 128 bit uuid - must match md device uuid */
__le64 events; /* 24 event counter for the bitmap (1)*/
__le64 events_cleared;/*32 event counter when last bit cleared (2) */
__le64 sync_size; /* 40 the size of the md device's sync range(3) */
__le32 state; /* 48 bitmap state information */
__le32 chunksize; /* 52 the bitmap chunk size in bytes */
__le32 daemon_sleep; /* 56 seconds between disk flushes */
__le32 write_behind; /* 60 number of outstanding write-behind writes */
__u8 pad[256 - 64]; /* set to zero */
} bitmap_super_t;
值得关注的,event记录对应MD设备的最近一个事件,这个事件也记录在MD的超级块中,在从磁盘加载时,可以通过和MD结构中的event比对来确认bitmap文件是否已经过期。如果过期,则将bitmap内的位全部设置为1。
Bitmap的内存结构
Bitmap内存中结构比磁盘文件要复杂得多,首先来看主要部分:
设备工作时,bitmap文件超级块也读入内存,保存在内存结构的sb_page中。
设备工作时,整个bitmap磁盘文件被映射到内存,保存在内存结构的filemap中,对应filemap,bitmap内存结构有filemap_attr数组,每4个bit对应filemap的一页。
Bp数组的每一个元素对应一个bitmap内存页,元素中的map指针指向存放内存bitmap的内存页,内存bitmap页保存bitmap内存结构。
内存中一个bitmap结构占用16bit,一个bitmap对应磁阵的一个条带。最高一位为是否需要同步标志,标志磁阵对应的条带是否需要同步;后面一位标志指针对应条带是否正在进行同步操作。低14位是一个计数器,表示对应磁阵条带段内正在进行的写操作个数。
* +--------+--------+------------------------------------------------+
* | resync | resync | counter |
* | needed | active | |
* | (0-1) | (0-1) | (0-16383) |
* +--------+--------+------------------------------------------------+
阅读(1206) | 评论(0) | 转发(0) |