在linear.c里(我参看的2.6.27.3的源码), 函数linear_conf里有这么一段:
...
min_spacing = conf->array_sectors / 2;
sector_div(min_spacing, PAGE_SIZE/sizeof(struct dev_info *));
/* min_spacing is the minimum spacing that will fit the hash
* table in one PAGE. This may be much smaller than needed.
* We find the smallest non-terminal set of consecutive devices
* that is larger than min_spacing as use the size of that as
* the actual spacing
*/
conf->hash_spacing = conf->array_sectors / 2;
for (i=0; i < cnt-1 ; i++) {
sector_t sz = 0;
int j;
for (j = i; j < cnt - 1 && sz < min_spacing; j++)
sz += conf->disks[j].size;
if (sz >= min_spacing && sz < conf->hash_spacing)
conf->hash_spacing = sz;
}
/* hash_spacing may be too large for sector_div to work with,
* so we might need to pre-shift
*/
conf->preshift = 0;
if (sizeof(sector_t) > sizeof(u32)) {
sector_t space = conf->hash_spacing;
while (space > (sector_t)(~(u32)0)) {
space >>= 1;
conf->preshift++;
}
}
...
然后又说:
...
/*
* Here we generate the linear hash table
* First calculate the device offsets.
*/
conf->disks[0].offset = 0;
for (i = 1; i < raid_disks; i++)
conf->disks.offset =
conf->disks[i-1].offset +
conf->disks[i-1].size;
table = conf->hash_table;
curr_offset = 0;
i = 0;
for (curr_offset = 0;
curr_offset < conf->array_sectors / 2;
curr_offset += conf->hash_spacing) {
while (i < raid_disks-1 &&
curr_offset >= conf->disks[i+1].offset)
i++;
*table ++ = conf->disks + i;
}
if (conf->preshift) {
conf->hash_spacing >>= conf->preshift;
/* round hash_spacing up so that when we divide by it,
* we err on the side of "too-low", which is safest.
*/
conf->hash_spacing++;
}
...
其中, conf->hash_spacing = conf->array_sectors / 2 , 将hash_spacing设置为待linear_conf的所有rdev设备的sector总和(也就是可以理解为该raid0设备总体的容量). 而while中conf->preshift++, 是由于conf0>hash_spacing可能太大, 也就是在开启了LBD 或 LSF的情况下, sector_t 取 u64, 因此 超过u32部分就要通过conf->preshift 来表达了. 而后面的 if (conf->preshift) { ...; conf->hash_spacing++;} hash_spacing再++, 是为了标志hash_spacing(2**9对齐)已经做了移位操作的.
类似的操作可以在raid0.c中 raid0_run函数中看到...
因此,综上, hash_spacing 是存储的和某个conf具体相关的raid0设备容量大小的. preshift是为了在hash_spacing过大时,定位查找的内容在哪个hash槽中移位作用的.
不知到理解正确与否...