[其他]代码库
if (test) list_for_each(p, &type->fs_supers) { /*遍历文件系统的super_block链表,p是链表头指针*/
struct super_block *old; /*走到循环里面,说明链表中有超级块,通过指针p来获取super_block结构体*/
old = list_entry(p, struct super_block, s_instances);/*s_instances是一个文件系统的超级块链表的指针,和fs_supers指向同一位置,即超级块*/
if (!test(old, data)) /*根据test函数控制流程,aufs的test函数一直返回1*/
continue;
if (!grab_super(old))/*old是可用的超级块,这个函数是把超级块的活动引用计数s_active加1,super_block现在是活动的,可用*/
goto retry;
if (s)/*已经查找到了,s就不需要了,其实s为NULL*/
destroy_super(s);/*如果s不为NULL的话,会执行kfree,释放s*/
return old; /*返回找到的super_block*/
}
static int grab_super(struct super_block *s)
{
s->s_count++; // 引用计数加1
spin_unlock(&sb_lock);
down_write(&s->s_umount);
if (s->s_root) { // 文件系统根目录对应的dentry存在
spin_lock(&sb_lock);
if (s->s_count > S_BIAS) { // 引用计数大于2^30,s_count初始化的时候值是S_BIAS,S_BIAS是2^30,上面加1保证能走到这里
atomic_inc(&s->s_active); // 活动引用计数加1
s->s_count--;// 引用计数减1
spin_unlock(&sb_lock);
return 1; // 成功获取一个活动引用,超级块s可用
}
spin_unlock(&sb_lock);
}
up_write(&s->s_umount);
put_super(s);// 这里引用计数也会减1,s_count的值一直是S_BIAS
yield();
return 0;
}