您的位置:首页 > 运维架构 > Linux

linux2.4内核 path_walk流程简析

2016-06-08 00:04 597 查看
这里以path_walk解析/usr/lib/glibc为例:

int path_walk(const char * name, struct nameidata *nd)
{
/*
nd是path_init返回的结构,包含了程序的根目录.因此,path_walk是从根目录开始解析。
开始时跳过路径/usr/lib/glibc中第一个'/',以后for循环处理剩下的字符串usr/lib/glibc
*/
while (*name=='/')
name++;
/*
root目录inode总是存在,因此inode非空
*/
inode = nd->dentry->d_inode;
for(;;) {
unsigned long hash;
/*struct qstr this作为整个for循环的中间变量,暂存路径在每次循环中的每个目录分量,如this.name=usr;this.name=lib;this.name=glibc*/
struct qstr this;
this.name = name;
c = *(const unsigned char *)name;

hash = init_name_hash();
/*字符串搜索,直到匹配到‘/’*/
/*这个while循环将传入的路径分解为目录分量,第一次取出usr分量,第二次取出lib*/
do {
name++;
hash = partial_name_hash(c, hash);
c = *(const unsigned char *)name;
} while (c && (c != '/'));
/*计算每个分量的长度*/
this.len = name - (const char *) this.name;
this.hash = end_name_hash(hash)
/*nd->dentry代表父节点,第一轮for循环的父节点就是根目录dnode结构.
每个dnode结构下挂在其子dnode结构,为了统一管理,父节点引入dnode队列数组,
子目录name的hash值相同,挂入同一个数组中的队列
*/
/*为了简单起见,假设每个目录分量的dnode结构都在内存中缓存着,因此cached_lookup
返回值都非空,即找到了子dnode结构
*/
dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
if (!dentry) {
dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE);
err = PTR_ERR(dentry);
if (IS_ERR(dentry))
break;
}
/*找到子dnode结构后,取出inode,然后进行下一次for循环*/
inode = dentry->d_inode;
nd->dentry = dentry;
}
}

由这段压缩版的path_walk及注释,可以清晰的看到path_walk的任务就是分解并取出路径中的子目录,取出子目录的dnode结构,以这个dnode为父节点,再找到这个节点下的子节点。周而复始直到找到目标。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux