📄 049_fs_namei_c.html
字号:
};</font><br id=hsa0>
<br id=b0bi>
/* SMP-safe */<br id=g4nc>
<font face="Courier New" id=ji4k>int
<font color=#38761d id=obfq><b id=b-j2>path_init</b></font>(const char
*name, unsigned int flags, struct nameidata *nd)<br id=glxf>
{<br id=tc9s>
<font color=#6aa84f id=l.5q><font color=#274e13 id=qo1f>nd->last_type
= <font color=#ff0000 id=y_:2>LAST_ROOT</font></font>;</font> /* if
there are only slashes... */<br id=ety0>
nd->flags = flags;<br id=ex9g>
if (*name=='/')
<font color=#0000ff id=wkvr>/*从根路径开始查找*/</font><br id=fgsm>
return walk_init_root(name,nd);
/*<font color=#0000ff id=kimx>请暂时忽略altroot,容稍后讨论(altroot编译时确定!)</font>*/<br id=ut4w>
</font><font face="Courier New" id=e28v><font color=#0000ff id=q99c>/*所以一般情况就是取current->fs->mnt,
root的引用*/<br id=p_ve>
/*从当前路径开始查找*/<br id=dik.>
</font>
read_lock(&current->fs->lock);<br id=rbiw>
nd->mnt =
mntget(current->fs->pwdmnt);<br id=hqfg>
nd->dentry = dget(current->fs->pwd);<br id=kb03>
read_unlock(&current->fs->lock);<br id=brr2>
return 1;<br id=y6-w>
}</font>
</p>
<p id=vb1d>
</p>
<p id=y8oa>
<font color=#0000ff id=fpoc size=4>dentry+mnt
唯一确定一个目录</font><br id=xv9d style="FONT-FAMILY:Courier New">
<span id=z1bf style="FONT-FAMILY:Courier New">首先一个问题是为什么dentry+mnt才能确定唯一的一个目录,
通过一个图来说明这个问题:(分析dcache的时候有这个图)仔细看这幅图, 这里演示一个目录下(d@) mount 了两个文件系统,
从/d11/d@ 进入hda3, 从/d12/d@进入hda4. 就是说从不同的地方到达d@就有不同的内容.
而从d@所属的nd->mnt就能够区分这种不同的路径.所以呢, 也只有mnt和dentry两个元素才决定唯一的一个目录.
而,根目录'/', 其mnt的parent是NULL, '/'目录的mnt->mnt_root就是</span>
</p>
<p id=vas6>
<span id=ro_r style="FONT-FAMILY:Courier New">这里的hda1的'/' dentry.
这个图还能说明其他很多问题...</span><br id=iu6y>
<img id=bcb2 src=049__fs_namei_c_images/dcbsxfpf_25gzfbcmd9.jpg style="WIDTH:436px; HEIGHT:635px">
</p>
<p id=dimb>
</p>
<p id=s2-7>
<br id=eicy>
<font color=#0000ff id=h1ko size=4>path walk 就是一个字符串解析的过程</font>
</p>
<p id=nad8>
<br id=k.px>
<font face="Courier New" id=ba-l style="FONT-FAMILY:Courier New">path_walk确实是一个字符串解析的过程,
其中 / . .. 代表了特殊的含义, 一个指定的路径, 在path walk的过程中, 沿着dentry和mnt组成的name
space树</font>
</p>
<p id=c.s1 style="FONT-FAMILY:Courier New">
找到指定的dentry和mnt.
</p>
<p id=ulic style="FONT-FAMILY:Courier New">
使path walk显得复杂的原因是我们要处理文件系统的其他事务:
</p>
<p id=d9vm style="FONT-FAMILY:Courier New">
1)从缓冲中查找detnry以加速处理 (dcache分析过了)<br id=mv3r>
</p>
<p id=cwtc style="FONT-FAMILY:Courier New">
2)从磁盘加载还不在这棵树中的内容
</p>
<p id=fiju style="FONT-FAMILY:Courier New">
3)处理 '..' 操作
</p>
<p id=a9jx style="FONT-FAMILY:Courier New">
4)处理link
</p>
<p id=m4ok style="FONT-FAMILY:Courier New">
5)处理mnt(dentry和mnt的混合树).
</p>
<p id=klhl style="FONT-FAMILY:Courier New">
</p>
<p id=u6y3 style="FONT-FAMILY:Courier New">
我们先看path walk中简单的部分, 比较复杂的稍后做详细说明.
</p>
<p align=justify dir=ltr id=kcow>
</p>
<p align=justify dir=ltr id=u6en style="FONT-FAMILY:Courier New">
<font id=m9cd size=-0><font id=ko-k size=2>/*<br id=yzks>
* 路径解析<br id=fisk>
*<br id=h:ga>
* 将路径解析为最终的dentry.<br id=xfyl>
*<br id=i3ty>
* We expect 'base' to be positive and a directory.<br id=xrmq>
*/<br id=fwpm>
int <font color=#38761d id=xqz1><b id=dz3u>path_walk</b></font>(const
char * <font color=#38761d id=cvg5>name</font>, struct nameidata
*<font color=#38761d id=ggg5>nd</font>)<br id=c3fa>
{<br id=c7j9>
....<br id=uc9v>
unsigned int lookup_flags =
nd->flags;</font></font>
</p>
<p align=justify dir=ltr id=ij2m style="FONT-FAMILY:Courier New">
<font id=f.3b size=-0><font id=es90 size=2> while
(*name=='/') <font color=#0000ff id=cmez>/*跳过多余的 '/'
*/</font><br id=euf->
name++;<br id=biz4>
if (!*name)
<font color=#0000ff id=qkq->/*路径中只有'/'*/</font><br id=erys>
goto
return_base;</font></font>
</p>
<p align=justify dir=ltr id=s2eq style="FONT-FAMILY:Courier New">
<font id=eric size=-0><font id=o:gq size=2> inode
= nd->dentry->d_inode;
<font color=#0000ff id=r8l_>/*要在这个inode中查找路径name中的第一个名字*/</font><br id=ru6x>
if (current->link_count)
<font color=#ff0000 id=iero>/*2.4
的这种处理方式有问题,2.6已经修正,见do_follow_link*/</font><br id=zffy>
lookup_flags
=
LOOKUP_FOLLOW;<font color=#0000ff id=okap>/*正在跟踪link,所以以后的查找也要这个flag*/</font><br id=lrb4>
</font></font>
</p>
<p align=justify dir=ltr id=q2jg style="FONT-FAMILY:Courier New">
<font id=d9eu size=-0><font id=cuhj size=2> /*
At this point we know we have a real path component. */<br id=n573>
for(;;) {<br id=d1mw>
</font></font>
</p>
<div id=u650 style=MARGIN-LEFT:40px>
<font color=#0b5394 id=y.ic size=-0><font id=oyj4 size=2> <span id=zy11 style="FONT-FAMILY:Courier New"> <font color=#3d85c6 id=zyle>
.... //略过些代码<br id=uqxm>
<font color=#ff00ff id=pwjc>
//计算要查找的name,this, 以及hash值</font><br id=lc6i>
</font></span></font></font>
</div>
<p align=justify dir=ltr id=o9i6 style="FONT-FAMILY:Courier New; MARGIN-LEFT:40px">
<font color=#3d85c6 id=grk9 size=-0><font id=iwh2 size=2> this.name
= name;<br id=nwq1>
c = *(const unsigned char
*)name;</font></font>
</p>
<p align=justify dir=ltr id=zanh style="FONT-FAMILY:Courier New; MARGIN-LEFT:40px">
<font color=#3d85c6 id=cg_8 size=-0><font id=eczw size=2> hash
= init_name_hash();<br id=y7.t>
do {<br id=tkeg>
name++;<br id=t7ta>
hash
= partial_name_hash(c, hash);<br id=ti_l>
c =
*(const unsigned char *)name;<br id=yl0p>
} while (c && (c != '/'));<br id=n9af>
this.len = name - (const char *)
this.name;<br id=i75l>
this.hash =
end_name_hash(hash);</font></font>
</p>
<p align=justify dir=ltr id=fznu style="FONT-FAMILY:Courier New; MARGIN-LEFT:40px">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -