find_next_zero_bit

unsigned long find_next_zero_bit(const unsigned long *addr, 
                                                                 unsigned long size,
                                                                 unsigned long offset)
这个函数的用意是在addr开始的地址段中,找到一个为0的位,函数调用成功则返回该位的索引,如果没找到,则返回size。所以可以看出搜索范围并不包含size这个点,因为即便size这个点为0,满足要求,但其返回值和失败时的返回值是相同的,所以也看作是失败。

搜索示意图如下:
再分析代码:
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
                 unsigned long offset)
{
    const unsigned long *p = addr + BITOP_WORD(offset);
    unsigned long result = offset & ~(BITS_PER_LONG-1); // result如上图,搜索起始点所在ULONG之前所有的bit
    unsigned long tmp;

    if (offset >= size)
        return size;
    size -= result; // 扣掉result,即size_new
    offset %= BITS_PER_LONG; // 取得所在ULONG中的偏移量,即offset_new
    if (offset) {
        tmp = *(p++);
        tmp |= ~0UL >> (BITS_PER_LONG - offset); // 将offset之内的bit全部置1,参看图1
        if (size < BITS_PER_LONG) // 这表示搜索范围在一个ULONG范围之内,参看图2
            goto found_first;
        if (~tmp) // tmp至少有一个0位,即tmp的
BPL - offset这一段中至少有一个0。
            goto found_middle;
        size -= BITS_PER_LONG;
        result += BITS_PER_LONG;
    }
    while (size & ~(BITS_PER_LONG-1)) { // 不断遍历size前的ULONG
        if (~(tmp = *(p++)))
            goto found_middle;
        result += BITS_PER_LONG;
        size -= BITS_PER_LONG;
    }
    if (!size) // 当size正好是整数个ULONG时,如果没找着,返回值就是原始的size,若不是,会依次进
found_first,然后found_middle
        return result;
    tmp = *p;

found_first:
    tmp |= ~0UL << size; // 将size以上部分全部置1
    if (tmp == ~0UL)    // offset~size或head~size之间没有0
        return result + size;   // 返回值即为传入的size
found_middle:
    return result + ffz(tmp); // 
ffz就是寻找unsigned long变量的第一个0位索引的宏
}