Chinaunix首页 | 论坛 | 博客
  • 博客访问: 626076
  • 博文数量: 120
  • 博客积分: 2284
  • 博客等级: 大尉
  • 技术积分: 1330
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-25 10:49
个人简介

http://guliqun1983.blog.163.com/blog/static/501116852011730535314/

文章分类
文章存档

2013年(23)

2012年(23)

2011年(74)

分类: LINUX

2013-04-24 10:30:30

声明:本文为原创
#####请转贴时保留以下内容######
作者GTT
本文档归属http://oldtown.cublog.cn/.转载请注明出处!
请提出宝贵意见Mail:mtloveft@hotmail.com
Linux Version:2.6.33
提示本文是关于file system 实现的介绍
 
目录和文件的查找是件很烦琐的事情,早期的linux版本,只有一个minix文件系统,还是很好查找的。
有了VSF之后,各个目录都有可能mount文件系统。这样导致查找的代码很多,而且很难读。而且文件
和目录查找是经常发生的事件,linuxOS首先到dir entry cache里查找,关于目录的查找,新生成时
会同时把dentry加入到cache里。方法实现上也很灵活,运用几个flag来对程序的控制。
总体上来说,对性能上的要求导致程序可读性下降了。
 
在 VFS 中各种操作, 如建立,删除目录,文件等,首先得进行父目录查找,找到父目录的相关信息,才可以继续操作,如果查找的过程中发现错误,比如父目录不存在,或者当前进程并无相应的权限等等,这种情况系统必然会进行相关处理。
 
查找一般都是从user_path_parent开始,一步一步查找。如果查找过程很清楚的话,那么fs的各种sys call就很简单了。
定义如下

static int user_path_parent(int dfd, const char __user *pathstruct nameidata *nd, char **name)

 
既然是查找,一定要有查找结果,查找结果放到什么地方?就放到一个临时结构里nameidata
变量一般都缩写为nd,这个结构里记录着查找过程中path name, 父目录 path, 根目录。
nameidata 的定义如下

struct nameidata {
    struct path path;
    struct qstr last;
    struct path root;
    unsigned int flags;
    int last_type;
    unsigned depth;
//link深度,每次link也++

    char * saved_names[MAX_NESTED_LINKS + 1];

    /* Intent data */
    union {
        struct open_intent open;
    } intent;
};

 
struct qstr last是放着要查找的path name,它的结构如下,

struct qstr {
    unsigned int hash;
    unsigned int len;
    const unsigned char *name;
};

 
它包含一个根据name 算出的hash值。
 
nameidata 结构中flags的定义如下

#define LOOKUP_FOLLOW     1
#define LOOKUP_DIRECTORY  2
#define LOOKUP_CONTINUE   4
#define LOOKUP_PARENT    16
#define LOOKUP_REVAL     64

 
flags对查找进行指示,LOOKUP_DIRECTORY意思是查找结果必须是目录。
LOOKUP_FOLLOW表示如果查找到的是symbol link ,则顺着symbol link继续查找。
当前进程有计数器current->total_link_count每次查找到一个link 则++
达到特定的值就退出,防止死循环。当发现有符号链接,则depth 也++
再次进入link_path_walk时设置LOOKUP_FOLLOW并清除LOOKUP_CONTINUE 以外的flags
 
nameidata 结构中last_type的定义如下

/* Type of the last component on LOOKUP_PARENT */
enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};

 
user_path_parent的处理流程如下
 
 
在搜索初始化时path_init,创建 nameidata,之后根据目录名称来设定他的值。
初始化过程在path_init里,如果搜索路径以'/'开头,
nd->root = current->fs->root
nd->path = current->fs->root
如果是AT_FDCWD,既当前工作路径的话
nd->path = current->fs->pwd
而不指定nd->root
nd->path 随着目录节点的深入而不断变化。
阅读(1142) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~