<html lang="zh-CN" xmlns:gdoc=""> <head> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <style type="text/css">
/* default css */
table {
font-size: 1em;
line-height: inherit;
}
div, address, ol, ul, li, option, select {
margin-top: 0px;
margin-bottom: 0px;
}
p {
margin: 0px;
}
body {
margin: 0px;
padding: 0px;
font-family: Verdana, sans-serif;
font-size: 10pt;
background-color: #ffffff;
}
h6 { font-size: 10pt }
h5 { font-size: 11pt }
h4 { font-size: 12pt }
h3 { font-size: 13pt }
h2 { font-size: 14pt }
h1 { font-size: 16pt }
blockquote {padding: 10px; border: 1px #DDD dashed }
a img {border: 0}
div.google_header, div.google_footer {
position: relative;
margin-top: 1em;
margin-bottom: 1em;
}
/* end default css */
/* default print css */
@media print {
body {
padding: 0;
margin: 0;
}
div.google_header, div.google_footer {
display: block;
min-height: 0;
border: none;
}
div.google_header {
flow: static(header);
}
/* used to insert page numbers */
div.google_header::before, div.google_footer::before {
position: absolute;
top: 0;
}
div.google_footer {
flow: static(footer);
}
/* always consider this element at the start of the doc */
div#google_footer {
flow: static(footer, start);
}
span.google_pagenumber {
content: counter(page);
}
span.google_pagecount {
content: counter(pages);
}
}
@page {
@top {
content: flow(header);
}
@bottom {
content: flow(footer);
}
}
/* end default print css */
/* custom css */
/* end custom css */
/* ui edited css */
body {
font-family: Arial;
font-size: 10.0pt;
line-height: normal;
background-color: #ffffff;
}
.documentBG {
background-color: #ffffff;
}
/* end ui edited css */
</style> </head> <body revision="dcbsxfpf_72kqwmrhj:358"> <div align=center id=vwb2>
<table align=center border=0 cellpadding=0 cellspacing=0 height=5716 id=rdfz width=800>
<tbody id=qc9l>
<tr id=gb0d>
<td height=5716 id=xuow valign=top width=100%>
<pre id=sl2q>2008-1-30</pre>
<pre id=nr:i><br id=q.qt> <br id=cm_y> 此文件是个巨无霸,对外接口已经很清晰的列了出来.我们标注了三个极为核心的函数.集中精力分析下. <<情景分析>>也是大力解析这几个<br id=d0dr>函数.其余函数随着分析之深入,逐步介绍,如果发现疑问,再就地解决.<br id=b:ex><span id=kz1r style="FONT-FAMILY:Courier New">/*</span><br id=gruw style="FONT-FAMILY:Courier New"><span id=wif0 style="FONT-FAMILY:Courier New"> *Interface:</span><br id=yj6g style="FONT-FAMILY:Courier New"><span id=zuem style="FONT-FAMILY:Courier New"> * int __user_walk(const char *name, unsigned flags, struct nameidata *nd)</span><br id=tx2_ style="FONT-FAMILY:Courier New"><span id=rhik style="FONT-FAMILY:Courier New"> * int </span><font color=#3333ff id=k0k4 style="FONT-FAMILY:Courier New"><b id=cmm1>open_namei</b></font><span id=szm9 style="FONT-FAMILY:Courier New">(const char * pathname, int flag, int mode, struct nameidata *nd)</span><br id=eon1 style="FONT-FAMILY:Courier New"><span id=ufnv style="FONT-FAMILY:Courier New"> * int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)</span><br id=wlt5 style="FONT-FAMILY:Courier New"><span id=rfc3 style="FONT-FAMILY:Courier New"> * int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, const char *link)</span><br id=dn08 style="FONT-FAMILY:Courier New"><span id=lbkg style="FONT-FAMILY:Courier New"> * int </span><font color=#3333ff id=v3h1 style="FONT-FAMILY:Courier New"><b id=xuox>path_walk</b></font><span id=yppf style="FONT-FAMILY:Courier New">(const char * name, struct nameidata *nd);</span><br id=r36s style="FONT-FAMILY:Courier New"><span id=d.yj style="FONT-FAMILY:Courier New"> * char * getname(const char * filename);</span><br id=fupu style="FONT-FAMILY:Courier New"><span id=ffud style="FONT-FAMILY:Courier New"> * int permission(struct inode * inode,int mask)</span><br id=si:p style="FONT-FAMILY:Courier New"><span id=r:je style="FONT-FAMILY:Courier New"> * int get_write_access(struct inode * inode);</span><br id=c-:o style="FONT-FAMILY:Courier New"><span id=f_ze style="FONT-FAMILY:Courier New"> * int deny_write_access(struct file * file)</span><br id=tpzr style="FONT-FAMILY:Courier New"><span id=r03o style="FONT-FAMILY:Courier New"> * void path_release(struct nameidata *nd)</span><br id=iqbr style="FONT-FAMILY:Courier New"><span id=xoo6 style="FONT-FAMILY:Courier New"> * int follow_down(struct vfsmount **mnt, struct dentry **dentry)</span><br id=feq. style="FONT-FAMILY:Courier New"><span id=b5ef style="FONT-FAMILY:Courier New"> * void set_fs_altroot(void)</span><br id=kxxz style="FONT-FAMILY:Courier New"><span id=zlmx style="FONT-FAMILY:Courier New"> * int </span><font color=#3333ff id=y_:8 style="FONT-FAMILY:Courier New"><b id=ab-:>path_init</b></font><span id=vpm9 style="FONT-FAMILY:Courier New">(const char *name, unsigned int flags, struct nameidata *nd)</span><br id=ohxf style="FONT-FAMILY:Courier New"><span id=lwkx style="FONT-FAMILY:Courier New"> * int vfs_follow_link(struct nameidata *nd, const char *link)</span><br id=dq0z style="FONT-FAMILY:Courier New"><span id=h08g style="FONT-FAMILY:Courier New"> *Sub Interface:</span><br id=m5g5 style="FONT-FAMILY:Courier New"><span id=d_q1 style="FONT-FAMILY:Courier New"> * struct dentry * lookup_hash(struct qstr *name, struct dentry * base)</span><br id=fv1c style="FONT-FAMILY:Courier New"><span id=b0hf style="FONT-FAMILY:Courier New"> *</span><br id=pfdd style="FONT-FAMILY:Courier New"><span id=k0_x style="FONT-FAMILY:Courier New"> *</span><br id=flrw style="FONT-FAMILY:Courier New"><span id=cl1m style="FONT-FAMILY:Courier New"> */</span><br id=e2.t>进行之前,先旁路些mini的函数,以免干扰主要思路:<br id=z1gx> <br id=qxwp>char * <font color=#38761d id=u.1j><b id=by:s>getname</b></font>(const char * filename) /*分配一个页面,将用户传递的参数复制到分配的页面中,并返回此页面指针*/<br id=c3qj> <font color=#38761d id=mvng><b id=iakh>putname</b></font>(name); /* 和上面函数配对,释放此页面*/<br id=ddt2>这对函数涉及到一个普遍常见的操作<br id=q_sz><font color=#38761d id=if4r><b id=cy..>set_fs</b></font>(get_ds());<br id=gbq1><font color=#38761d id=l-_w><b id=dfsy>set_fs</b></font>(old_ds) <br id=sj4e>常见于内核中操作文件的操作,这对操作的含义在下面这个函数中:<br id=y37m>static inline int<b id=x.4-> do_getname</b>(const char *filename, char *page)<br id=xjd4>{<br id=ocme> int retval;<br id=lwem> unsigned long len = PATH_MAX + 1;<br id=tav-><br id=z2rf> if ((unsigned long) <b id=xbg0>filename </b>>= <font color=#cc0000 id=ryp4>TASK_SIZE</font>) { <font color=#3d85c6 id=ylcx>/*如果是内核传递的参数*/</font><br id=ymuj> if (!segment_eq(<font color=#cc0000 id=fr_0><font color=#0b5394 id=rflh><b id=nt_w>get_fs</b></font>()</font>, <font color=#cc0000 id=f7st>KERNEL_DS</font>)) <font color=#0b5394 id=rslx>/*则必须addr limit 等于KERNEL_DS: 不是cpu的寄存器...*/</font><br id=z_-d> return -EFAULT;<br id=mo6m> } else if (TASK_SIZE - (unsigned long) filename < PAGE_SIZE) <font color=#0000ff id=mlvr>/*内核传递的参数跳过这个检查*/</font><br id=ab-o> len = TASK_SIZE - (unsigned long) filename;<br id=k57q> .........<br id=dlgu>}<br id=vcch><br id=tndk><br id=qb7q>分析permission之前看看inode的几个相关变量:<br id=ybyb>struct inode {<br id=b9uu> struct list_head i_hash;<br id=ou7r> struct list_head i_list;<br id=xccb> struct list_head i_dentry;<br id=dnl1> <br id=gf.a> struct list_head i_dirty_buffers;<br id=u8-u><br id=b45h> unsigned long i_ino;<br id