也许可以从函数load_super0查一查0.9从什么区域读取的超级块信息。
c
|- get_dev_size(fd, devname, &dsize); // 获取磁盘size
|- ioctl(fd, BLKGETSIZE64, &ldsize); // 发送一个ioctl给磁盘获取size。
|- offset = MD_NEW_SIZE_SECTORS(dsize>>9); // 获取扇区偏移。
c
// md_p.h
/*
* RAID superblock.
*
* The RAID superblock maintains some statistics on each RAID configuration.
* Each real device in the RAID set contains it near the end of the device.
* Some of the ideas are copied from the ext2fs implementation.
*
* We currently use 4096 bytes as follows:
*
* word offset function
*
* 0 - 31 Constant generic RAID device information.
* 32 - 63 Generic state information.
* 64 - 127 Personality specific information.
* 128 - 511 12 32-words descriptors of the disks in the raid set.
* 512 - 911 Reserved.
* 912 - 1023 Disk specific descriptor.
*/
/*
* If x is the real device size in bytes, we return an apparent size of:
*
* y = (x & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES
*
* and place the 4kB superblock at offset y.
*/
#define MD_RESERVED_BYTES (64 * 1024)
#define MD_RESERVED_SECTORS (MD_RESERVED_BYTES / 512)
#define MD_RESERVED_BLOCKS (MD_RESERVED_BYTES / BLOCK_SIZE)
#define MD_NEW_SIZE_SECTORS(x) ((x & ~(MD_RESERVED_SECTORS - 1)) - MD_RESERVED_SECTORS)
#define MD_NEW_SIZE_BLOCKS(x) ((x & ~(MD_RESERVED_BLOCKS - 1)) - MD_RESERVED_BLOCKS)
所以需要研究下元数据存放位置的计算方式?
假设设备的磁盘大小为10G,换算成字节10 * 1024 * 1024 * 1024 = 10737418240Byte
,用来被保存raid superblock的总大小为64KB。
宏MD_NEW_SIZE_SECTORS用来计算元数据存放的扇区位置,传参为磁盘的扇区数x,如果磁盘大小为10G,磁盘扇区数为20971520
个扇区。
MD_RESERVED_SECTORS大小为128个sectors。
(20971520- & ~(127)) - 128 = 20971392
,1010000000000000000000000 & 0000000 - 128 = 20971392
,对于磁盘大小为10G的磁盘来讲,刚好保留了最后64K用来存放软raid元数据,当然也包括bitmap相关信息。
~127
的目的是为了将20971520低七位清零,形成一种64K对齐的效果,对齐之后取最后一个64KB作为元数据的存放区域,对于磁盘非64K对齐的区域软raid不进行管理。