写给自己看的 linux 2.6查找inode之path_lookup
2016-03-12 17:08
525 查看
写给自己看的 linux 2.6查找inode之path_lookup
path_lookup是根据给定的文件名查找inode。其函数原型为:
path_lookup(const char *name, unsigned int flags,struct nameidata *nd)
其中有一个nameidata的实例nd,它既是规定查找的起点,也是查找结束后的终点。在开始查找时,它包含起点的dentry和快速字符串(quick string,包含字符串本身、长度及哈希值)。如果查找的路径名为:/usr/bin/emacs 那么刚开始存的就是/对应的目录项,最后存的就是emacs对应的目录项。
接下来path_lookup会调用do_path_lookup(AT_FDCWD, name, flags, nd);
1088 static int do_path_lookup(int dfd, const char *name, 1089 unsigned int flags, struct nameidata *nd) 1090 { 1091 int retval = path_init(dfd, name, flags, nd); 1092 if (!retval) 1093 retval = path_walk(name, nd); 1094 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && 1095 nd->path.dentry->d_inode)) 1096 audit_inode(name, nd->path.dentry); 1097 if (nd->root.mnt) { 1098 path_put(&nd->root); 1099 nd->root.mnt = NULL; 1100 } 1101 return retval; 1102 }
其中path_init会做相关的查找起点的初始化操作。如果路径名中包含根目录的话,那么nd就会包含根目录的dentry,如果不包含的话,那么nd就包含当前进程工作目录的dentry。
接下来就大致说下在具体的查找函数
__link_path_walk(const char *name, struct nameidata *nd)
书上说这是内核中最长的一部分之一,但是很多地方还是很好理解的,我就说下几个自己觉得重要的地方。
首先是进入一个大循环,为了把完整的路径名分成一个个对应的dentry,就必须要通过循环来解决,而\就是对应的dentry的分隔符。进入循环后,要检查是否有进入当前目录的权限,要进入该目录是要有对该目录有执行权限的,而err=exec_permission_lite(inode);就是干这个事的,没有权限的话就会返回错误。
在就是对当前的部分路径名计算一个hash值,这样可以用来在dcache中查找是否缓存了对应的dentry。代码如下:
881 do { 882 name++; 883 hash = partial_name_hash(c, hash); 884 c = *(const unsigned char *)name; 885 } while (c && (c != '/')); 886 this.len = name - (const char *) this.name; 887 this.hash = end_name_hash(hash);
然后会对.和..目录进行特殊处理,.目录就直接continue啦进入下次循环,而..的操作还比较复杂,要进入上层目录的话,上次目录可能属于不同的文件系统,可能因为当前目录就是根目录就还是在当前目录啊。所以,就调用了 follow_dotdot(nd);然后还是continue,进行下一轮的处理。
再就是 do_lookup(nd, &this, &next); 该函数会使得next里面存的是对应的目录项(inode值已填充好),do_lookup会先在dcache中找是否缓存过了对应的目录项,如果没有的话,就调用文件系统底层的查找函数来查找。
当然,如果inode对应的是个符号链接的话(我觉得系统应该是通过inode->i_op->follow_link来判断该inode是不是符号链接,如果不是的话,follow_link就为NULL),那么还要跟下去。
别的我觉得没啥好说的了。。看代码还是挺好理解的。
相关文章推荐
- Linux socket 初步
- Linux Kernel 4.0 RC5 发布!
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- Linux 下无损图片压缩小工具介绍