写给自己看的 linux 2.6查找inode之path_lookup

写给自己看的 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),那么还要跟下去。

别的我觉得没啥好说的了。。看代码还是挺好理解的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值