Linux虚拟文件系统–文件路径名的解析(2)–回退父目录

上文介绍了解析文件路径名的一个通体的过程,这里再把其中的一些细节拿出来进行分析。首先对于文件名的特点,可以分为三类:普通文件名,’.’和’..’,对于’.’的处理很简单,因为它表示当前目录,因此直接通过continue进入下一轮查找即可,对于’..’,也就是退回到父目录,本身也不是一件难事,但是这里要考虑到几个特殊情况,先看看内核处理’..’的方法:

相关阅读:Linux虚拟文件系统–文件路径名的解析(2)–回退父目录

static __always_inline void follow_dotdot(struct nameidata *nd) { set_root(nd); while(1) { struct vfsmount *parent; struct dentry *old = nd->path.dentry; /*如果当前所处的目录即为根目录则break*/ if (nd->path.dentry == nd->root.dentry && nd->path.mnt == nd->root.mnt) { break; } spin_lock(&dcache_lock); //如果当前所处的目录不为当前路径所属文件系统的根目录,也就是说可以直接向上退一级 if (nd->path.dentry != nd->path.mnt->mnt_root) { nd->path.dentry = dget(nd->path.dentry->d_parent);//当前的目录退到上一级 spin_unlock(&dcache_lock); dput(old); break; } /*下面的情况对应于当前所处的目录为文件系统的根目录*/ spin_unlock(&dcache_lock); spin_lock(&vfsmount_lock); parent = nd->path.mnt->mnt_parent;//取父文件系统 if (parent == nd->path.mnt) {//父文件系统即为本身,则表明没有父文件系统,,直接break spin_unlock(&vfsmount_lock); break; } mntget(parent);//增加父文件系统的引用计数 nd->path.dentry = dget(nd->path.mnt->mnt_mountpoint);//取当前文件系统的挂载点,这样就退回到了父文件系统 spin_unlock(&vfsmount_lock); dput(old); mntput(nd->path.mnt); nd->path.mnt = parent;//设置当前路径的mnt为父文件系统 } /*一般情况下,前面的操作可以保证返回到上级目录,但是有一种情况就是 当前目录的上级目录有可能还挂载了其他的文件系统,这样会隐藏之前的文件系统, follow_mount()用来处理这种情况*/ follow_mount(&nd->path); }

while循环里面的路径可以分为三种:

1.当前目录为nd中已经预设好的根目录,也就是说无法再向上退一层了,这种情况直接break

2.当前目录不为所属文件系统的根目录,这种情况是最常见的,可以向上退一层

3.当前目录为所属文件系统的挂载点,这种情况下,后退一层的话则会进入到父文件系统中,所以先要做一个文件系统的交换,再通过while(1)循环回到前面两种情况

千万个不眠的夜里,你一直让我感动,只是因为相信有个人会爱我一生一世。

Linux虚拟文件系统–文件路径名的解析(2)–回退父目录

相关文章:

你感兴趣的文章:

标签云: