⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _2_4_050_fs_readdir_c.html

📁 重读linux 2.4.2o所写的笔记
💻 HTML
字号:
  <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: Verdana;        font-size: 10.0pt;    line-height: normal;    background-color: #ffffff;  }    .documentBG {    background-color: #ffffff;  }  /* end ui edited css */</style>   </head>  <body  revision="dcbsxfpf_211fx8xtr7j:41">      <div align=center id=k65l>
  <table align=center border=0 cellpadding=0 cellspacing=0 height=5716 id=ux-b width=800>
    <tbody id=zkj6>
    <tr id=vw.g>
      <td height=5716 id=mt62 valign=top width=100%>
        <pre id=hi_a>2008-4-22<br id=cz1p><br id=i-2_>fs/readdir.c<br id=g2jk><br id=tpu_>此文件很纯净,就是你ls的时候所调用的函数, 在 <a href=Doc?id=dcbsxfpf_60cr7cm55r id=hry_ title=UML>UML</a> 一文中已经讨论过这个文件,这里忽略64bit的处理,仅简单看看.<br id=cicv><br id=oh2o>int vfs_readdir(struct file *file, filldir_t filler, void *buf)<br id=xfkv>{<br id=nn.l>	.....<br id=tdgw>	if (!IS_DEADDIR(inode)) {<br id=rqwz>		lock_kernel();<br id=fd:k>		res = file-&gt;f_op-&gt;readdir(file, buf, filler); <span id=mo5- style=COLOR:#38761d>/*就是调用fop的readdir*/</span><br id=aiqy>		unlock_kernel();<br id=a7ok>	}<br id=gr4m>        .....<br id=ya48>	return res;<br id=lr.2>}<br id=g3d_><br id=y-3c>对于不同文件系统的readdir实现不同, 其中对于像shm fs,ramfs这种纯粹虚拟的文件系统,这里提供了一个统一的实现:<br id=hpu->int dcache_readdir(struct file * filp, void * dirent, filldir_t filldir)<br id=q-v.>{<br id=g19z>	struct dentry *dentry = filp-&gt;f_dentry;<br id=a2z1>	struct dentry *cursor = filp-&gt;private_data; <span id=jz-v style=COLOR:#0000ff>/*dcache_dir_open 将cursor 设置为dentry ''.''*/</span><br id=p3b7>                                        <span id=bv9. style=COLOR:#0000ff> /* cursor d_child 挂入了filp-&gt;f_dentry-&gt;d_subdirs */</span><br id=dfnp>	struct list_head *p, *q = &amp;cursor-&gt;d_child; <br id=o7ia>	ino_t ino;<br id=cq5i>	int i = filp-&gt;f_pos;<br id=bggp><br id=zlu1>	switch (i) {<br id=j7i1>                 .... /*. 和.. 处理,略*/<br id=tz.y>		default:<br id=p.rz>			spin_lock(&amp;dcache_lock);<br id=tk2:>			if (filp-&gt;f_pos == 2) { <span id=emxe style=COLOR:#0000ff>/* pos=2 意味从头开始 */</span><br id=alp1>				list_del(q);<span id=fh_s style=COLOR:#0000ff>/*将cursor从f_dentry-&gt;d_subdirs 删除*/</span><br id=ewme>				list_add(q, &amp;dentry-&gt;d_subdirs);<span id=uv.x style=COLOR:#0000ff>/*又加回来,从而位于subdir之首*/</span><br id=v11m>			}<br id=lr0z><br id=rzmy>			<span id=o9j. style=COLOR:#0000ff>/*从cursor 的下一个subdir 开始*/</span><br id=fh8l>			for (p=q-&gt;next; <span id=vg1: style=COLOR:#0000ff>p != &amp;dentry-&gt;d_subdirs</span>; p=p-&gt;next) {<br id=kd-a>				struct dentry *next;<br id=la:0>				next = list_entry(p, struct dentry, d_child);<br id=xt4e>				if (<span id=ybnu style=COLOR:#0000ff>d_unhashed(next) || !next-&gt;d_inode</span>) /*只有加入hash的dentry并且有inode(未删除)*/<br id=lxrj>					continue;         /*删除dentry可能还在hash中*/<br id=jl4_><br id=rrvg>				spin_unlock(&amp;dcache_lock);<br id=f5_9>				if (filldir(dirent, next-&gt;d_name.name, next-&gt;d_name.len, filp-&gt;f_pos, <br id=nqmm>				next-&gt;d_inode-&gt;i_ino, dt_type(next-&gt;d_inode)) &lt; 0)<br id=pesu>					return 0;<br id=x3vz>				spin_lock(&amp;dcache_lock);<br id=q3xv>				/* next is still alive */<br id=uj6g>				list_del(q); <span id=x0qx style=COLOR:#0000ff>/*q 是cursor, 后移一个位置 */</span><br id=i5t_>				list_add(q, p);<br id=bhbn>				p = q; <span id=zm_b style=COLOR:#0000ff>/*从cursor 取下一个subdir*/</span><br id=v2ti>				filp-&gt;f_pos++;<br id=podh>			}<br id=txii>			spin_unlock(&amp;dcache_lock);<br id=w_w2>	}<br id=c1a->	return 0;<br id=lo3e>}<br id=w.y_><br id=cedi>至于ext2的readdir操作就不多说了,不是很难.<br id=hq4.>static int ext2_readdir(struct file * filp,<br id=m9v2>			 void * dirent, filldir_t filldir)<br id=tjln>{<br id=mnh5>	offset = filp-&gt;f_pos &amp; (sb-&gt;s_blocksize - 1); <span id=saiw style=COLOR:#0000ff>/*计算文件pos在blk中的偏移*/</span><br id=bktr><br id=z:7q>	while (!error &amp;&amp; !stored &amp;&amp; filp-&gt;f_pos &lt; inode-&gt;i_size) { <br id=d7n9>                <span id=ana4 style=COLOR:#ff0000>/*stored:如果已读取当前blk内的dentry,就不读下个blk的entry了.. 咋想的呢?*/</span><br id=nnur>		blk = (filp-&gt;f_pos) &gt;&gt; EXT2_BLOCK_SIZE_BITS(sb); /*计算blk no*/<br id=byg2>		bh = ext2_bread (inode, blk, 0, &amp;err); <span id=b4w2 style=COLOR:#0000ff>/*文件内blk到文件系统blk no的换算:ext自己的三级表...*/</span><br id=h9zh>		if (!bh) { <span id=pbku style=COLOR:#0000ff>/*有个洞? ...有点问题,打印错误信息,继续*/</span><br id=l.jz>             		.....<br id=mtds>			filp-&gt;f_pos += sb-&gt;s_blocksize - offset;<br id=fta.>			continue;<br id=id9v>		}<br id=k9nx>		<span id=v.3m style=COLOR:#0000ff>/* Do the readahead :找找文件块到文件系统块的转换表,然后预读,不像ext2_bread是block的*/</span><br id=wr-t>		.....<br id=zldw>		<br id=pm18>revalidate:<br id=qkim>                /*这个修改的侦测只对f_pos所在blk有效,有限的避免竞争情况下的不一致*/<br id=uton>		if (filp-&gt;f_version != inode-&gt;i_version) { <span id=dy5w style=COLOR:#0000ff>/*f_version用于监视文件是否被修改过*/<br id=mvqv>                     /*不一样的情况下记录的f_ops可能是有问题的,再次从0到offset重新开始扫描下,停到有问题的块上..*/<br id=lp4r></span>			for (i = 0; i &lt; sb-&gt;s_blocksize &amp;&amp; i &lt; offset; ) {<br id=jot1>				de = (struct ext2_dir_entry_2 *) <br id=ws10>					(bh-&gt;b_data + i);<br id=b3w->                                <span id=dywj style=COLOR:#0000ff>停到第一个有问题的entry上,</span><br id=ai59>			}<br id=ud:j>                        ....<br id=ptpu>			filp-&gt;f_pos = (filp-&gt;f_pos &amp; ~(sb-&gt;s_blocksize - 1))  <span id=h0rp style=COLOR:#0000ff>/*更新文件的f_ops*/</span><br id=obqr>				| offset;<br id=g400>			filp-&gt;f_version = inode-&gt;i_version;   <br id=l3sn>		}<br id=krzd>		<br id=dtre>		while (!error &amp;&amp; filp-&gt;f_pos &lt; inode-&gt;i_size <br id=lz:x>		       &amp;&amp; offset &lt; sb-&gt;s_blocksize) { <span id=vrrx style=COLOR:#0000ff>/*尝试读取此blk内所有目录项*/</span><br id=eovc>			de = (struct ext2_dir_entry_2 *) (bh-&gt;b_data + offset);<br id=yds_>			if (!ext2_check_dir_entry ("ext2_readdir", inode, de,<br id=o6-w>						   bh, offset)) {<br id=m3bs>				<span id=sx6b style=COLOR:#0000ff>/*如果有问题,停止读取(ext2删除dentry时把前一个dentry的长度扩大,覆盖被删除的dentry*/</span><br id=y.5l style=COLOR:#0000ff><span id=ztae style=COLOR:#0000ff>                                .... /*跟新f_pos,返回*/</span><br id=f3fa>				return stored;<br id=ttjt>			}<br id=q5oa>			offset += le16_to_cpu(de-&gt;rec_len);<br id=jemp>			if (le32_to_cpu(de-&gt;inode)) {<br id=f7qk>				/* copy 出去一个 */<br id=yxh7>                                /* 缓冲区满就返回了*/<br id=h.ce>                                if (version != filp-&gt;f_version) <span id=lz25 style=COLOR:#0000ff>/*竞争发生时重新validate*/</span><br id=tqeg>					goto revalidate;<br id=gxxw>				stored ++;<br id=a4ez>			}<br id=cotf>			filp-&gt;f_pos += le16_to_cpu(de-&gt;rec_len);<br id=yla:>		}<br id=n_vq>		offset = 0;<br id=n:pp>		brelse (bh);<br id=lgi.>	} //end while<br id=u1:i>	UPDATE_ATIME(inode);<br id=ig:a>	return 0;<br id=ffxn>}<br id=viyv><br id=y0c.></pre>
      </td>
    </tr>
    </tbody>
  </table>
</div></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -