位图的初始化是由函数
bitmap_create来实现,此函数在创建带有bitmap的MD/RAID设备时调用,主要完成bitmap从磁盘到内存的加载。
Bitmap可以存放在指定文件中,也可以存放在组建MD/RAID设备的磁盘中,如果是存放在文件中,可以用bitmap_file指针来表示,这里仅介绍bitmap存在磁盘中的情况。
函数bitmap_create
此函数流程如下:
主要完成如下操作:
1. 调用函数read_sb_page,从mddev->disks链表头开始遍历所有的成员盘,从底层设备读取超级块的信息。如果读取成功,则此函数直接返回;
假设创建raid时指定三块成员盘为disk0、disk1、disk2,那么在这里只读了disk2的数据就会返回了;
读取前:
bio->bi_sector=rdev->sb_start+offset+index
* (PAGE_SIZE/512)=8+8+0=16;
bio->bi_size=roundup(sizeof(bitmap_super_t);
bdev_logical_block_size(rdev->bdev))=roundup(256+4096)=4096;
page->index=0;
读取后:
page的引用计数加1;
page->private=NULL;
读出来的数据赋值给bitmap->sb_page,并经过内存映射,得到MD超级块数据信息,记录在指针[bitmap_super_t *sb]中;
判断sb->events<mddev->events,如果是,说明此bitmap数据已经失效,需要将sb->state标记上BITMAP_STALE。
2. 计算bitmap位图大小,得出需要的page个数,然后给bitmap赋值;
bitmap->chunks =
chunks; // 把dev_sectors分成chunks个部分,每个大小为bitmap_chunk
bitmap->pages =
pages; //计算出来给bp数组申请的page个数
bitmap->counter_bits
= COUNTER_BITS = 16;
再按照算出来的pages个数,申请bitmap->bp结构。
3. 从底层磁盘读取bitmap,通过调用函数
bitmap_init_from_disk完成,后面会讲;
4. 调用函数bitmap_update_sb,将bitmap信息写入每一个active成员盘中(raid_disks>=0&&!FAULT)。
函数bitmap_init_from_disk
从函数名字理解,就可以看出这个函数是从组成MD/RAID设备的磁盘中读取位图,用来初始化结构bitmap信息。
其传入参数为:
1. bitmap结构
2. start:在磁盘完好没有降级 或者 bitmap没有失效时start=mddev->recovery_cp,否则start=0
mddev->recovery_cp这个值在MD/RAID设备有重构时,记录的是重构的位置
其流程如下图:
函数说明:
1. file_page_index计算当前chunk在哪个filemap page中,计算公式为:
(Chunk+(sizeof(bitmap_super_t)
<< 3)) >> (PAGE_SHIFT + 3)
2. file_page_offset计算当前chunk在该page中的偏移,计算公式为:
(Chunk+(sizeof(bitmap_super_t)
<< 3)) & ((PAGE_SIZE<<3) - 1)
未完 -- 待续
阅读(2311) | 评论(0) | 转发(0) |