static int path_init(int dfd, const char *name, unsigned int flags, struct nameidata *nd)
{
......
if (*name=='/')
{
set_root(nd);
nd->path = nd->root;
path_get(&nd->root);
}
else if(dfd == AT_FDCWD)
..........
}
在if (*name=='/')分支,调用了set_root,set_root里面有调用path_get(&nd->root),set_root执行完后,又调用了一次path_get(&nd->root),调用两次是什么情况?
path_get
是用于增加引用计数的。
在 set_root
里面, *root = fs->root
给当前进程的 fs->root
增加了一次引用,所以需要 path_get(root)
,这句实际上应该是 path_get(&fs->root)
,两种写法是等价的,只是前面的写法似乎可以减少一次寻址的开销。
在 set_root
之后, nd->path = nd->root
给这个 nd->root
增加了一次引用,所以需要 path_get(&nd->root)
。
如果把赋值、引用计数两件事情封装起来,就比较好理解了:
void path_assign_and_get(struct path *dest, struct path *src)
{
*dest = *src;
path_get(src);
}
static const char *path_init(struct nameidata *nd, unsigned flags)
{
...
path_assign_and_get(&nd->root, ¤t->fs->root);
path_assign_and_get(&nd->path, &nd->root);
...
}