﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-jieao111-文章分类-unix culture</title><link>http://www.cppblog.com/jieao111/category/10089.html</link><description>专注于计算机科学和unix文化</description><language>zh-cn</language><lastBuildDate>Sun, 05 Apr 2009 02:45:31 GMT</lastBuildDate><pubDate>Sun, 05 Apr 2009 02:45:31 GMT</pubDate><ttl>60</ttl><item><title>MINIX文件系统浅摭</title><link>http://www.cppblog.com/jieao111/articles/78879.html</link><dc:creator>王超杰</dc:creator><author>王超杰</author><pubDate>Fri, 03 Apr 2009 13:54:00 GMT</pubDate><guid>http://www.cppblog.com/jieao111/articles/78879.html</guid><wfw:comment>http://www.cppblog.com/jieao111/comments/78879.html</wfw:comment><comments>http://www.cppblog.com/jieao111/articles/78879.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jieao111/comments/commentRss/78879.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jieao111/services/trackbacks/78879.html</trackback:ping><description><![CDATA[<p>近些天来复习软考，看操作系统时又看到《操作系统：设计与实现》这本书，上学期看的时候由于日语二级，一直没有自己仔细研究，现在有些时间，顺便总结一下。</p>
<p>书上关于文件系统各个方面的介绍基本已经很完备了，然而我总感觉有点不足：不能从整体上理解文件系统。怎么从整体上理解文件系统呢？个人感觉应该象一个机器一样，能够在大脑勾画出它的大致的框架，再以一些基本的操作为例，观察一下它工作的流程。本文便由此着手，将MINIX文件系统给大家展示一下。</p>
<p>文件系统说白了就是外存的管理。操作系统有进程管理，内存管理，I/O管理，当然外存管理也必不可少，那么文件系统到底是个什么样子呢，请看下面这张图：</p>
<img height=475 alt="" src="http://www.cppblog.com/images/cppblog_com/jieao111/1.jpg" width=857 border=0><br>&nbsp;
<p>第一层，一个磁盘包含了几个分区（partition），每一个分区就代表一个文件系统（file system），就像我们刚买时电脑分区一样，比如我的电脑就分了四个区：C盘，D盘，E盘和G盘，那么我的电脑就包含了四个文件系统。而每个分区又包含了很多柱面（cylinder group）。关于硬盘的详细介绍请看<a href="http://download.csdn.net/source/1175149">这里</a>。</p>
<p>&nbsp;</p>
<p>第二层往下（包含第二层）这个图就是所呈现的文件系统的概述。从左至友，引导块，超块，然后是柱面，柱面里又有i结点位图，块位图，i结点数组，数据区等等。</p>
<p>引导块里面是电脑启动时用到的信息，下面直接抄书：</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">Each&nbsp;file&nbsp;system&nbsp;begins&nbsp;with&nbsp;a&nbsp;boot&nbsp;block.&nbsp;This&nbsp;contains&nbsp;executable&nbsp;code.&nbsp;The&nbsp;size&nbsp;of&nbsp;a&nbsp;boot&nbsp;block&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;always&nbsp;</span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">&nbsp;bytes&nbsp;(two&nbsp;disk&nbsp;sectors),&nbsp;even&nbsp;though&nbsp;MINIX&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&nbsp;may&nbsp;(and&nbsp;by&nbsp;</span><span style="COLOR: #0000ff">default</span><span style="COLOR: #000000">&nbsp;does)&nbsp;use&nbsp;a&nbsp;larger&nbsp;block&nbsp;size&nbsp;elsewhere.&nbsp;When&nbsp;the&nbsp;computer&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;turned&nbsp;on,&nbsp;the&nbsp;hardware&nbsp;reads&nbsp;the&nbsp;boot&nbsp;block&nbsp;from&nbsp;the&nbsp;boot&nbsp;device&nbsp;into&nbsp;memory,&nbsp;jumps&nbsp;to&nbsp;it,&nbsp;and&nbsp;begins&nbsp;executing&nbsp;its&nbsp;code.&nbsp;The&nbsp;boot&nbsp;block&nbsp;code&nbsp;begins&nbsp;the&nbsp;process&nbsp;of&nbsp;loading&nbsp;the&nbsp;operating&nbsp;system&nbsp;itself.&nbsp;Once&nbsp;the&nbsp;system&nbsp;has&nbsp;been&nbsp;booted,&nbsp;the&nbsp;boot&nbsp;block&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;not&nbsp;used&nbsp;any&nbsp;more.&nbsp;Not&nbsp;every&nbsp;disk&nbsp;drive&nbsp;can&nbsp;be&nbsp;used&nbsp;</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;a&nbsp;boot&nbsp;device,&nbsp;but&nbsp;to&nbsp;keep&nbsp;the&nbsp;structure&nbsp;uniform,&nbsp;every&nbsp;block&nbsp;device&nbsp;has&nbsp;a&nbsp;block&nbsp;reserved&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;boot&nbsp;block&nbsp;code.&nbsp;At&nbsp;worst&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">&nbsp;strategy&nbsp;wastes&nbsp;one&nbsp;block.To&nbsp;prevent&nbsp;the&nbsp;hardware&nbsp;from&nbsp;trying&nbsp;to&nbsp;boot&nbsp;an&nbsp;unbootable&nbsp;device,&nbsp;a&nbsp;magic&nbsp;number&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;placed&nbsp;at&nbsp;a&nbsp;known&nbsp;location&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;boot&nbsp;block&nbsp;when&nbsp;and&nbsp;only&nbsp;when&nbsp;the&nbsp;executable&nbsp;code&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;written&nbsp;to&nbsp;the&nbsp;device.&nbsp;When&nbsp;booting&nbsp;from&nbsp;a&nbsp;device,&nbsp;the&nbsp;hardware&nbsp;(actually,&nbsp;the&nbsp;BIOS&nbsp;code)&nbsp;will&nbsp;refuse&nbsp;to&nbsp;attempt&nbsp;to&nbsp;load&nbsp;from&nbsp;a&nbsp;device&nbsp;lacking&nbsp;the&nbsp;magic&nbsp;number.&nbsp;Doing&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">&nbsp;prevents&nbsp;inadvertently&nbsp;</span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;garbage&nbsp;</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;a&nbsp;boot&nbsp;program.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>&nbsp;</p>
<p>超块是比较重要的一个块，里面装入了文件系统的布局信息，它的主要功能是给出文件系统不同部分的大小。</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">The&nbsp;main&nbsp;function&nbsp;of&nbsp;the&nbsp;superblock&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;to&nbsp;tell&nbsp;the&nbsp;file&nbsp;system&nbsp;how&nbsp;big&nbsp;the&nbsp;various&nbsp;pieces&nbsp;of&nbsp;the&nbsp;file&nbsp;system&nbsp;are.&nbsp;Given&nbsp;the&nbsp;block&nbsp;size&nbsp;and&nbsp;the&nbsp;number&nbsp;of&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">nodes,&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;easy&nbsp;to&nbsp;calculate&nbsp;the&nbsp;size&nbsp;of&nbsp;the&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">node&nbsp;bitmap&nbsp;and&nbsp;the&nbsp;number&nbsp;of&nbsp;blocks&nbsp;of&nbsp;inodes.&nbsp;For&nbsp;example,&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;a&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">KB&nbsp;block,&nbsp;each&nbsp;block&nbsp;of&nbsp;the&nbsp;bitmap&nbsp;has&nbsp;</span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">&nbsp;bytes&nbsp;(</span><span style="COLOR: #000000">8192</span><span style="COLOR: #000000">&nbsp;bits),&nbsp;and&nbsp;thus&nbsp;can&nbsp;keep&nbsp;track&nbsp;of&nbsp;the&nbsp;status&nbsp;of&nbsp;up&nbsp;to&nbsp;</span><span style="COLOR: #000000">8192</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">nodes.&nbsp;(Actually&nbsp;the&nbsp;first&nbsp;block&nbsp;can&nbsp;handle&nbsp;only&nbsp;up&nbsp;to&nbsp;</span><span style="COLOR: #000000">8191</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">nodes,&nbsp;since&nbsp;there&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;no&nbsp;0th&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">node,&nbsp;but&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;given&nbsp;a&nbsp;bit&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;bitmap,&nbsp;anyway).&nbsp;For&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,</span><span style="COLOR: #000000">000</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">nodes,&nbsp;two&nbsp;bitmap&nbsp;blocks&nbsp;are&nbsp;needed.&nbsp;Since&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">nodes&nbsp;each&nbsp;occupy&nbsp;</span><span style="COLOR: #000000">64</span><span style="COLOR: #000000">&nbsp;bytes,&nbsp;a&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">KB&nbsp;block&nbsp;holds&nbsp;up&nbsp;to&nbsp;</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">nodes.&nbsp;With&nbsp;</span><span style="COLOR: #000000">64</span><span style="COLOR: #000000">&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">nodes,&nbsp;four&nbsp;disk&nbsp;blocks&nbsp;are&nbsp;needed&nbsp;to&nbsp;contain&nbsp;them&nbsp;all.</span></div>
<p>为了防止本文成为国内大多数填鸭式文章（一味填充资料）的样子，这里我就不给出超块的详细图了，考虑到我们只是从整体上了解一下文件系统，并不深究其里，感兴趣的朋友可以下载《操作系统：设计与实现》这本书，上面讲的很清楚，另外，本文引用的那样e文也可略过。<br>i结点位图，块位图跟踪i结点和块的使用情况，比如创建文件时会看i结点位图哪位是0，创建后会把这一位置1。块位图也是如此管理存储区。然而实际上超块的内存副本里包含了指向了第一空闲的i结点位和第一个空闲区的指针，从而消除了查找时的麻烦，另外删除文件时，也要重新修改这个指针。</p>
然后就是i结点数组和数据区，看下面这张图<img height=361 alt="" src="http://www.cppblog.com/images/cppblog_com/jieao111/2.jpg" width=854 border=0>&nbsp;<br>&nbsp;
<p>从哪开始看呢，不如自上而下，先从目录看起（图中directory block），在MINIX中每个目录项由文件名和i结点编号组成，看目录的各种实现见书上，i结点内包含了文件的大多数信息（访问权限，文件长度，等等）。当我们打开文件时，首先在目录内找到文件名，进而可以根据i结点号连接到相应的i结点。i结点最后三个域又可以指向数据区。再来张i结点图：<br><br><img height=698 alt="" src="http://www.cppblog.com/images/cppblog_com/jieao111/0.jpg" width=562 border=0>。</p>
<p>&nbsp;</p>
<span style="FONT-SIZE: 14pt">&nbsp;<br>静态的文件系统的组成就大致如此了。再来看动态的，先来看一下文件系统工作时需要的数据结构：<br><br></span><img height=322 alt="" src="http://www.cppblog.com/images/cppblog_com/jieao111/4.jpg" width=759 border=0><br>
<p>我们知道进程表一共由内核，内存管理器和文件系统管理器来维护（书中第一章）。进程表里面包含了打开的文件描述字，引用计数等一些信息。每个项对应于i结点表中的一项（内存中包含了关于文件系统的三个表，如上图）。恩？中间那个file table是干什么的，为什么会出现这个呢？看下面这个。大意就是说由于子进程需要和父进程的文件偏移位同步，放在进程表和i结点内都不行，所以多搞了个表：</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Code_Closed_Image_135539 onclick="this.style.display='none'; Code_Closed_Text_135539.style.display='none'; Code_Open_Image_135539.style.display='inline'; Code_Open_Text_135539.style.display='inline';" height=16 src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" width=11 align=top><img id=Code_Open_Image_135539 style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_135539.style.display='none'; Code_Closed_Image_135539.style.display='inline'; Code_Closed_Text_135539.style.display='inline';" height=16 src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width=11 align=top><span id=Code_Closed_Text_135539 style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Code_Open_Text_135539 style="DISPLAY: none"><br><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">5.6</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">7</span><span style="COLOR: #000000">.&nbsp;File&nbsp;Descriptors<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>Once&nbsp;a&nbsp;file&nbsp;has&nbsp;been&nbsp;opened,&nbsp;a&nbsp;file&nbsp;descriptor&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;returned&nbsp;to&nbsp;the&nbsp;user&nbsp;process&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;use&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;subsequent&nbsp;read&nbsp;and&nbsp;write&nbsp;calls.&nbsp;In&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">&nbsp;section&nbsp;we&nbsp;will&nbsp;look&nbsp;at&nbsp;how&nbsp;file&nbsp;descriptors&nbsp;are&nbsp;managed&nbsp;within&nbsp;the&nbsp;file&nbsp;system.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>Like&nbsp;the&nbsp;kernel&nbsp;and&nbsp;the&nbsp;process&nbsp;manager,&nbsp;the&nbsp;file&nbsp;system&nbsp;maintains&nbsp;part&nbsp;of&nbsp;the&nbsp;process&nbsp;table&nbsp;within&nbsp;its&nbsp;address&nbsp;space.&nbsp;Three&nbsp;of&nbsp;its&nbsp;fields&nbsp;are&nbsp;of&nbsp;particular&nbsp;interest.&nbsp;The&nbsp;first&nbsp;two&nbsp;are&nbsp;pointers&nbsp;to&nbsp;the&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">nodes&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;the&nbsp;root&nbsp;directory&nbsp;and&nbsp;the&nbsp;working&nbsp;directory.&nbsp;Path&nbsp;searches,&nbsp;such&nbsp;</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;that&nbsp;of&nbsp;Fig.&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">16</span><span style="COLOR: #000000">,&nbsp;always&nbsp;begin&nbsp;at&nbsp;one&nbsp;or&nbsp;the&nbsp;other,&nbsp;depending&nbsp;on&nbsp;whether&nbsp;the&nbsp;path&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;absolute&nbsp;or&nbsp;relative.&nbsp;These&nbsp;pointers&nbsp;are&nbsp;changed&nbsp;by&nbsp;the&nbsp;chroot&nbsp;and&nbsp;chdir&nbsp;system&nbsp;calls&nbsp;to&nbsp;point&nbsp;to&nbsp;the&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;root&nbsp;or&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;working&nbsp;directory,&nbsp;respectively.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">--------------------------------------------------------------------------------</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>[Page&nbsp;</span><span style="COLOR: #000000">562</span><span style="COLOR: #000000">]<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>The&nbsp;third&nbsp;interesting&nbsp;field&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;process&nbsp;table&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;an&nbsp;array&nbsp;indexed&nbsp;by&nbsp;file&nbsp;descripttor&nbsp;number.&nbsp;It&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;used&nbsp;to&nbsp;locate&nbsp;the&nbsp;proper&nbsp;file&nbsp;when&nbsp;a&nbsp;file&nbsp;descriptor&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;presented.&nbsp;At&nbsp;first&nbsp;glance,&nbsp;it&nbsp;might&nbsp;seem&nbsp;sufficient&nbsp;to&nbsp;have&nbsp;the&nbsp;k</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">th&nbsp;entry&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">&nbsp;array&nbsp;just&nbsp;point&nbsp;to&nbsp;the&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">node&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;the&nbsp;file&nbsp;belonging&nbsp;to&nbsp;file&nbsp;descriptor&nbsp;k.&nbsp;After&nbsp;all,&nbsp;the&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">node&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;fetched&nbsp;into&nbsp;memory&nbsp;when&nbsp;the&nbsp;file&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;opened&nbsp;and&nbsp;kept&nbsp;there&nbsp;until&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;closed,&nbsp;so&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;sure&nbsp;to&nbsp;be&nbsp;available.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>Unfortunately,&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">&nbsp;simple&nbsp;plan&nbsp;fails&nbsp;because&nbsp;files&nbsp;can&nbsp;be&nbsp;shared&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;subtle&nbsp;ways&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;MINIX&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;well&nbsp;</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;UNIX).&nbsp;The&nbsp;trouble&nbsp;arises&nbsp;because&nbsp;associated&nbsp;with&nbsp;each&nbsp;file&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;a&nbsp;</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">bit&nbsp;number&nbsp;that&nbsp;indicates&nbsp;the&nbsp;next&nbsp;</span><span style="COLOR: #0000ff">byte</span><span style="COLOR: #000000">&nbsp;to&nbsp;be&nbsp;read&nbsp;or&nbsp;written.&nbsp;It&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">&nbsp;number,&nbsp;called&nbsp;the&nbsp;file&nbsp;position,&nbsp;that&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;changed&nbsp;by&nbsp;the&nbsp;lseek&nbsp;system&nbsp;call.&nbsp;The&nbsp;problem&nbsp;can&nbsp;be&nbsp;stated&nbsp;easily:&nbsp;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Where&nbsp;should&nbsp;the&nbsp;file&nbsp;pointer&nbsp;be&nbsp;stored?</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>The&nbsp;first&nbsp;possibility&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;to&nbsp;put&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">node.&nbsp;Unfortunately,&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;two&nbsp;or&nbsp;more&nbsp;processes&nbsp;have&nbsp;the&nbsp;same&nbsp;file&nbsp;open&nbsp;at&nbsp;the&nbsp;same&nbsp;time,&nbsp;they&nbsp;must&nbsp;all&nbsp;have&nbsp;their&nbsp;own&nbsp;file&nbsp;pointers,&nbsp;since&nbsp;it&nbsp;would&nbsp;hardly&nbsp;</span><span style="COLOR: #0000ff">do</span><span style="COLOR: #000000">&nbsp;to&nbsp;have&nbsp;an&nbsp;lseek&nbsp;by&nbsp;one&nbsp;process&nbsp;affect&nbsp;the&nbsp;next&nbsp;read&nbsp;of&nbsp;a&nbsp;different&nbsp;process.&nbsp;Conclusion:&nbsp;the&nbsp;file&nbsp;position&nbsp;cannot&nbsp;go&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;inode.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>What&nbsp;about&nbsp;putting&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;process&nbsp;table</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">&nbsp;Why&nbsp;not&nbsp;have&nbsp;a&nbsp;second&nbsp;array,&nbsp;paralleling&nbsp;the&nbsp;file&nbsp;descriptor&nbsp;array,&nbsp;giving&nbsp;the&nbsp;current&nbsp;position&nbsp;of&nbsp;each&nbsp;file</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">&nbsp;This&nbsp;idea&nbsp;does&nbsp;not&nbsp;work&nbsp;either,&nbsp;but&nbsp;the&nbsp;reasoning&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;more&nbsp;subtle.&nbsp;Basically,&nbsp;the&nbsp;trouble&nbsp;comes&nbsp;from&nbsp;the&nbsp;semantics&nbsp;of&nbsp;the&nbsp;fork&nbsp;system&nbsp;call.&nbsp;When&nbsp;a&nbsp;process&nbsp;forks,&nbsp;both&nbsp;the&nbsp;parent&nbsp;and&nbsp;the&nbsp;child&nbsp;are&nbsp;required&nbsp;to&nbsp;share&nbsp;a&nbsp;single&nbsp;pointer&nbsp;giving&nbsp;the&nbsp;current&nbsp;position&nbsp;of&nbsp;each&nbsp;open&nbsp;file.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>To&nbsp;better&nbsp;understand&nbsp;the&nbsp;problem,&nbsp;consider&nbsp;the&nbsp;</span><span style="COLOR: #0000ff">case</span><span style="COLOR: #000000">&nbsp;of&nbsp;a&nbsp;shell&nbsp;script&nbsp;whose&nbsp;output&nbsp;has&nbsp;been&nbsp;redirected&nbsp;to&nbsp;a&nbsp;file.&nbsp;When&nbsp;the&nbsp;shell&nbsp;forks&nbsp;off&nbsp;the&nbsp;first&nbsp;program,&nbsp;its&nbsp;file&nbsp;position&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;standard&nbsp;output&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">.&nbsp;This&nbsp;position&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;then&nbsp;inherited&nbsp;by&nbsp;the&nbsp;child,&nbsp;which&nbsp;writes,&nbsp;say,&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;KB&nbsp;of&nbsp;output.&nbsp;When&nbsp;the&nbsp;child&nbsp;terminates,&nbsp;the&nbsp;shared&nbsp;file&nbsp;position&nbsp;must&nbsp;now&nbsp;be&nbsp;</span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>Now&nbsp;the&nbsp;shell&nbsp;reads&nbsp;some&nbsp;more&nbsp;of&nbsp;the&nbsp;shell&nbsp;script&nbsp;and&nbsp;forks&nbsp;off&nbsp;another&nbsp;child.&nbsp;It&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;essential&nbsp;that&nbsp;the&nbsp;second&nbsp;child&nbsp;inherit&nbsp;a&nbsp;file&nbsp;position&nbsp;of&nbsp;</span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">&nbsp;from&nbsp;the&nbsp;shell,&nbsp;so&nbsp;it&nbsp;will&nbsp;begin&nbsp;writing&nbsp;at&nbsp;the&nbsp;place&nbsp;where&nbsp;the&nbsp;first&nbsp;program&nbsp;left&nbsp;off.&nbsp;If&nbsp;the&nbsp;shell&nbsp;did&nbsp;not&nbsp;share&nbsp;the&nbsp;file&nbsp;position&nbsp;with&nbsp;its&nbsp;children,&nbsp;the&nbsp;second&nbsp;program&nbsp;would&nbsp;overwrite&nbsp;the&nbsp;output&nbsp;from&nbsp;the&nbsp;first&nbsp;one,&nbsp;instead&nbsp;of&nbsp;appending&nbsp;to&nbsp;it.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>As&nbsp;a&nbsp;result,&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;not&nbsp;possible&nbsp;to&nbsp;put&nbsp;the&nbsp;file&nbsp;position&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;process&nbsp;table.&nbsp;It&nbsp;really&nbsp;must&nbsp;be&nbsp;shared.&nbsp;The&nbsp;solution&nbsp;used&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;UNIX&nbsp;and&nbsp;MINIX&nbsp;</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;to&nbsp;introduce&nbsp;a&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">,&nbsp;shared&nbsp;table,&nbsp;filp,&nbsp;which&nbsp;contains&nbsp;all&nbsp;the&nbsp;file&nbsp;positions.&nbsp;Its&nbsp;use&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;illustrated&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;Fig.&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">39</span><span style="COLOR: #000000">.&nbsp;By&nbsp;having&nbsp;the&nbsp;file&nbsp;position&nbsp;truly&nbsp;shared,&nbsp;the&nbsp;semantics&nbsp;of&nbsp;fork&nbsp;can&nbsp;be&nbsp;implemented&nbsp;correctly,&nbsp;and&nbsp;shell&nbsp;scripts&nbsp;work&nbsp;properly.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>Although&nbsp;the&nbsp;only&nbsp;thing&nbsp;that&nbsp;the&nbsp;filp&nbsp;table&nbsp;really&nbsp;must&nbsp;contain&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;the&nbsp;shared&nbsp;file&nbsp;position,&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;convenient&nbsp;to&nbsp;put&nbsp;the&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">node&nbsp;pointer&nbsp;there,&nbsp;too.&nbsp;In&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">&nbsp;way,&nbsp;all&nbsp;that&nbsp;the&nbsp;file&nbsp;descriptor&nbsp;array&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;process&nbsp;table&nbsp;contains&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;a&nbsp;pointer&nbsp;to&nbsp;a&nbsp;filp&nbsp;entry.&nbsp;The&nbsp;filp&nbsp;entry&nbsp;also&nbsp;contains&nbsp;the&nbsp;file&nbsp;mode&nbsp;(permission&nbsp;bits),&nbsp;some&nbsp;flags&nbsp;indicating&nbsp;whether&nbsp;the&nbsp;file&nbsp;was&nbsp;opened&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;a&nbsp;special&nbsp;mode,&nbsp;and&nbsp;a&nbsp;count&nbsp;of&nbsp;the&nbsp;number&nbsp;of&nbsp;processes&nbsp;</span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;it,&nbsp;so&nbsp;the&nbsp;file&nbsp;system&nbsp;can&nbsp;tell&nbsp;when&nbsp;the&nbsp;last&nbsp;process&nbsp;</span><span style="COLOR: #0000ff">using</span><span style="COLOR: #000000">&nbsp;the&nbsp;entry&nbsp;has&nbsp;terminated,&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;order&nbsp;to&nbsp;reclaim&nbsp;the&nbsp;slot.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></span></div>
<br>下面，好戏开始了：<br>开始动态的看看文件系统的工作过程，MINIX文件系统工作一般都是基于这么一个过程：用户调用一个系统函数，然后就创建一条消息，包含了相应的参数。这条消息然后被送到文件系统，并阻塞以等待文件系统的响应。文件系统在接收到消息后，以消息类型为索引查找过程表，并调用相应的过程处理请求。<br>
<p><br><o:p>比如打开文件的操作，文件系统从消息中提取相应的信息，比如绝对路径，然后它就根据目录进行查找（关于目录的查找，本文没有涉及，也参考书吧）。从目录中找到相应的i结点号（图2），然后得到相应的i结点，并把它载入内存的i节点表中。直到文件关闭前，它一直在内存的i结点表内。然后可以根据i结点的指针就可以得到数据了，加载到内存就行了。内存中的每个i结点还有一个计数器，当文件多次打开时，在内存中只保留一个i结点的副本，但是每次打开文件时，计数器加1，每次关闭该文件时，计数器减1。只有计数器为0时，才将它从i结点表中删除。。注意不要将这个计数器和硬盘上的i结点的计数器相混，那个i结点的引用计数为0时（没有目录指向该i结点），文件才从磁盘上删除。。<br><br>另外引用书中讲的一个read的调用来结束本文，这段e文还是很值得一读的，我就不自己敲了：</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">5.6</span><span style="COLOR: #000000">.</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">.&nbsp;An&nbsp;Example:&nbsp;The&nbsp;READ&nbsp;System&nbsp;Call<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>As&nbsp;we&nbsp;shall&nbsp;see&nbsp;shortly,&nbsp;most&nbsp;of&nbsp;the&nbsp;code&nbsp;of&nbsp;the&nbsp;file&nbsp;system&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;devoted&nbsp;to&nbsp;carrying&nbsp;</span><span style="COLOR: #0000ff">out</span><span style="COLOR: #000000">&nbsp;system&nbsp;calls.&nbsp;Therefore,&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;appropriate&nbsp;that&nbsp;we&nbsp;conclude&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">&nbsp;overview&nbsp;with&nbsp;a&nbsp;brief&nbsp;sketch&nbsp;of&nbsp;how&nbsp;the&nbsp;most&nbsp;important&nbsp;call,&nbsp;read,&nbsp;works.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>When&nbsp;a&nbsp;user&nbsp;program&nbsp;executes&nbsp;the&nbsp;statement<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>n&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;read(fd,&nbsp;buffer,&nbsp;nbytes);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>to&nbsp;read&nbsp;an&nbsp;ordinary&nbsp;file,&nbsp;the&nbsp;library&nbsp;procedure&nbsp;read&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;called&nbsp;with&nbsp;three&nbsp;parameters.&nbsp;It&nbsp;builds&nbsp;a&nbsp;message&nbsp;containing&nbsp;these&nbsp;parameters,&nbsp;along&nbsp;with&nbsp;the&nbsp;code&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;read&nbsp;</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;the&nbsp;message&nbsp;type,&nbsp;sends&nbsp;the&nbsp;message&nbsp;to&nbsp;the&nbsp;file&nbsp;system,&nbsp;and&nbsp;blocks&nbsp;waiting&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;the&nbsp;reply.&nbsp;When&nbsp;the&nbsp;message&nbsp;arrives,&nbsp;the&nbsp;file&nbsp;system&nbsp;uses&nbsp;the&nbsp;message&nbsp;type&nbsp;</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;an&nbsp;index&nbsp;into&nbsp;its&nbsp;tables&nbsp;to&nbsp;call&nbsp;the&nbsp;procedure&nbsp;that&nbsp;handles&nbsp;reading.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>This&nbsp;procedure&nbsp;extracts&nbsp;the&nbsp;file&nbsp;descriptor&nbsp;from&nbsp;the&nbsp;message&nbsp;and&nbsp;uses&nbsp;it&nbsp;to&nbsp;locate&nbsp;the&nbsp;filp&nbsp;entry&nbsp;and&nbsp;then&nbsp;the&nbsp;i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">node&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;the&nbsp;file&nbsp;to&nbsp;be&nbsp;read&nbsp;(see&nbsp;Fig.&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">39</span><span style="COLOR: #000000">).&nbsp;The&nbsp;request&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;then&nbsp;broken&nbsp;up&nbsp;into&nbsp;pieces&nbsp;such&nbsp;that&nbsp;each&nbsp;piece&nbsp;fits&nbsp;within&nbsp;a&nbsp;block.&nbsp;For&nbsp;example,&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;the&nbsp;current&nbsp;file&nbsp;position&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">600</span><span style="COLOR: #000000">&nbsp;and&nbsp;</span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">&nbsp;bytes&nbsp;have&nbsp;been&nbsp;requested,&nbsp;the&nbsp;request&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;split&nbsp;into&nbsp;two&nbsp;parts,&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">600</span><span style="COLOR: #000000">&nbsp;to&nbsp;</span><span style="COLOR: #000000">1023</span><span style="COLOR: #000000">,&nbsp;and&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1024</span><span style="COLOR: #000000">&nbsp;to&nbsp;</span><span style="COLOR: #000000">1623</span><span style="COLOR: #000000">&nbsp;(assuming&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">KB&nbsp;blocks).<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>For&nbsp;each&nbsp;of&nbsp;these&nbsp;pieces&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;turn,&nbsp;a&nbsp;check&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;made&nbsp;to&nbsp;see&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;the&nbsp;relevant&nbsp;block&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;cache.&nbsp;If&nbsp;the&nbsp;block&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;not&nbsp;present,&nbsp;the&nbsp;file&nbsp;system&nbsp;picks&nbsp;the&nbsp;least&nbsp;recently&nbsp;used&nbsp;buffer&nbsp;not&nbsp;currently&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;use&nbsp;and&nbsp;claims&nbsp;it,&nbsp;sending&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;disk&nbsp;device&nbsp;driver&nbsp;to&nbsp;rewrite&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;dirty.&nbsp;Then&nbsp;the&nbsp;disk&nbsp;driver&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;asked&nbsp;to&nbsp;fetch&nbsp;the&nbsp;block&nbsp;to&nbsp;be&nbsp;read.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">--------------------------------------------------------------------------------</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>[Page&nbsp;</span><span style="COLOR: #000000">566</span><span style="COLOR: #000000">]<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>Once&nbsp;the&nbsp;block&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;cache,&nbsp;the&nbsp;file&nbsp;system&nbsp;sends&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;system&nbsp;task&nbsp;asking&nbsp;it&nbsp;to&nbsp;copy&nbsp;the&nbsp;data&nbsp;to&nbsp;the&nbsp;appropriate&nbsp;place&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;user</span><span style="COLOR: #000000">'</span><span style="COLOR: #000000">s&nbsp;buffer&nbsp;(i.e.,&nbsp;bytes&nbsp;600&nbsp;to&nbsp;1023&nbsp;to&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;buffer,&nbsp;and&nbsp;bytes&nbsp;1024&nbsp;to&nbsp;1623&nbsp;to&nbsp;offset&nbsp;424&nbsp;within&nbsp;the&nbsp;buffer).&nbsp;After&nbsp;the&nbsp;copy&nbsp;has&nbsp;been&nbsp;done,&nbsp;the&nbsp;file&nbsp;system&nbsp;sends&nbsp;a&nbsp;reply&nbsp;message&nbsp;to&nbsp;the&nbsp;user&nbsp;specifying&nbsp;how&nbsp;many&nbsp;bytes&nbsp;have&nbsp;been&nbsp;copied.</span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>When&nbsp;the&nbsp;reply&nbsp;comes&nbsp;back&nbsp;to&nbsp;the&nbsp;user,&nbsp;the&nbsp;library&nbsp;function&nbsp;read&nbsp;extracts&nbsp;the&nbsp;reply&nbsp;code&nbsp;and&nbsp;returns&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;the&nbsp;function&nbsp;value&nbsp;to&nbsp;the&nbsp;caller.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>One&nbsp;extra&nbsp;step&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;not&nbsp;really&nbsp;part&nbsp;of&nbsp;the&nbsp;read&nbsp;call&nbsp;itself.&nbsp;After&nbsp;the&nbsp;file&nbsp;system&nbsp;completes&nbsp;a&nbsp;read&nbsp;and&nbsp;sends&nbsp;a&nbsp;reply,&nbsp;it&nbsp;initiates&nbsp;reading&nbsp;additional&nbsp;blocks,&nbsp;provided&nbsp;that&nbsp;the&nbsp;read&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;from&nbsp;a&nbsp;block&nbsp;device&nbsp;and&nbsp;certain&nbsp;other&nbsp;conditions&nbsp;are&nbsp;met.&nbsp;Since&nbsp;sequential&nbsp;file&nbsp;reads&nbsp;are&nbsp;common,&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;reasonable&nbsp;to&nbsp;expect&nbsp;that&nbsp;the&nbsp;next&nbsp;blocks&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;a&nbsp;file&nbsp;will&nbsp;be&nbsp;requested&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;next&nbsp;read&nbsp;request,&nbsp;and&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">&nbsp;makes&nbsp;it&nbsp;likely&nbsp;that&nbsp;the&nbsp;desired&nbsp;block&nbsp;will&nbsp;already&nbsp;be&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;cache&nbsp;when&nbsp;it&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;needed.&nbsp;The&nbsp;number&nbsp;of&nbsp;blocks&nbsp;requested&nbsp;depends&nbsp;upon&nbsp;the&nbsp;size&nbsp;of&nbsp;the&nbsp;block&nbsp;cache;&nbsp;</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;many&nbsp;</span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">32</span><span style="COLOR: #000000">&nbsp;additional&nbsp;blocks&nbsp;may&nbsp;be&nbsp;requested.&nbsp;The&nbsp;device&nbsp;driver&nbsp;does&nbsp;not&nbsp;necessarily&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">this</span><span style="COLOR: #000000">&nbsp;many&nbsp;blocks,&nbsp;and&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;at&nbsp;least&nbsp;one&nbsp;block&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;returned&nbsp;a&nbsp;request&nbsp;</span><span style="COLOR: #0000ff">is</span><span style="COLOR: #000000">&nbsp;considered&nbsp;successful.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
</o:p>
<img src ="http://www.cppblog.com/jieao111/aggbug/78879.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jieao111/" target="_blank">王超杰</a> 2009-04-03 21:54 <a href="http://www.cppblog.com/jieao111/articles/78879.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>