PathWalk,顾名思义,就是根据路径找到目标的文件或目录,作为每次open()或opendir()都要执行的过程,其重要性不言而喻。
PathWalk中的很重要的一个概念就是nameidata,这个对象可以看作是PathWalk过程的上下文的封装,记录当前查找所用的路径,如果查找结束,则记录最终的目标路径。作为”上下文”,其主要工作就是封装了在一个过程中各个子逻辑都需要的信息,并随着过程的进行贯穿于各个子过程供其在需要时使用。
在内核中,PathWalk的主要逻辑整理如下
path_init(name, nd) //根据name初始化nd lookup_last(nd, &path) //此时path还是空的 walk_component() handle_dots() lookup_fast(nd, path, &inode) __d_lookup_rcu() struct vfsmount *mnt = nd->path.mnt path->mnt = mnt path->dentry = dentry __follow_mount_rcu(nd, path, inode) mounted = __lookup_mnt() path->mnt = &mounted->mnt //用下溯文件系统的mounted来更新path path->dentry = mounted->mnt.mnt_root; return 0 ; //不需look_up时 return 1 ; //仍需look_up时 lookup_slow() __lookup_hash() lookup_dcache() d_lookup() d_alloc() lookup_real() path->mnt = nd->path.mnt path->dentry = dentry follow_managed() path_to_nameidate(path,nd) //根据新path设置nameidata nd->path.mnt = path->mnt nd->inode = inode
这段逻辑使用上下文nameidata对象作为PathWalk过程中局部的全局变量,实现递归的目录搜索。