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; |
} |