6.html

来自「linux 0.11中文版 有注释」· HTML 代码 · 共 596 行 · 第 1/4 页

HTML
596
字号
<a name='L119'>
<a name='L120'><i><font color='green'>//// 使指定设备在高速缓冲区中的数据无效。</font></i>
<a name='L121'><i><font color='green'>// 扫描高速缓冲中的所有缓冲块,对于指定设备的缓冲区,复位其有效(更新)标志和已修改标志。</font></i>
<a name='L122'><b>void</b> <b>inline</b>
<a name='L123'><a href='../S/6.html#L181' title='Refered from 181 in fs/buffer.c.'>invalidate_buffers</a> (<b>int</b> dev)
<a name='L124'><font color='red'>{</font>
<a name='L125'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L126'>  <b>struct</b> buffer_head *bh;
<a name='L127'>
<a name='L128'>  bh = start_buffer;
<a name='L129'>  <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; <a href='../S/31.html#L64' title='Defined at 64 in include/linux/fs.h.'>NR_BUFFERS</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++, bh++)
<a name='L130'>    <font color='red'>{</font>
<a name='L131'>      <b>if</b> (bh-&gt;b_dev != <a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>)     <i><font color='green'>// 如果不是指定设备的缓冲块,则</font></i>
<a name='L132'>        <b>continue</b>;               <i><font color='green'>// 继续扫描下一块。</font></i>
<a name='L133'>      <a href='../S/6.html#L64' title='Defined at 64 in fs/buffer.c.'>wait_on_buffer</a> (bh);      <i><font color='green'>// 等待该缓冲区解锁(如果已被上锁)。</font></i>
<a name='L134'><i><font color='green'>// 由于进程执行过睡眠等待,所以需要再判断一下缓冲区是否是指定设备的。</font></i>
<a name='L135'>      <b>if</b> (bh-&gt;b_dev == <a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>)
<a name='L136'>        bh-&gt;b_uptodate = bh-&gt;b_dirt = 0;
<a name='L137'>    <font color='red'>}</font>
<a name='L138'><font color='red'>}</font>
<a name='L139'>
<a name='L140'><i><font color='green'>/*</font></i>
<a name='L141'><i><font color='green'>* This routine checks whether a floppy has been changed, and</font></i>
<a name='L142'><i><font color='green'>* invalidates all buffer-cache-entries in that case. This</font></i>
<a name='L143'><i><font color='green'>* is a relatively slow routine, so we have to try to minimize using</font></i>
<a name='L144'><i><font color='green'>* it. Thus it is called only upon a 'mount' or 'open'. This</font></i>
<a name='L145'><i><font color='green'>* is the best way of combining speed and utility, I think.</font></i>
<a name='L146'><i><font color='green'>* People changing diskettes in the middle of an operation deserve</font></i>
<a name='L147'><i><font color='green'>* to loose :-)</font></i>
<a name='L148'><i><font color='green'>*</font></i>
<a name='L149'><i><font color='green'>* NOTE! Although currently this is only for floppies, the idea is</font></i>
<a name='L150'><i><font color='green'>* that any additional removable block-device will use this routine,</font></i>
<a name='L151'><i><font color='green'>* and that mount/open needn't know that floppies/whatever are</font></i>
<a name='L152'><i><font color='green'>* special.</font></i>
<a name='L153'><i><font color='green'>*/</font></i>
<a name='L154'><i><font color='green'>/*</font></i>
<a name='L155'><i><font color='green'>* 该子程序检查一个软盘是否已经被更换,如果已经更换就使高速缓冲中与该软驱</font></i>
<a name='L156'><i><font color='green'>* 对应的所有缓冲区无效。该子程序相对来说较慢,所以我们要尽量少使用它。</font></i>
<a name='L157'><i><font color='green'>* 所以仅在执行'mount'或'open'时才调用它。我想这是将速度和实用性相结合的</font></i>
<a name='L158'><i><font color='green'>* 最好方法。若在操作过程当中更换软盘,会导致数据的丢失,这是咎由自取?。</font></i>
<a name='L159'><i><font color='green'>*</font></i>
<a name='L160'><i><font color='green'>* 注意!尽管目前该子程序仅用于软盘,以后任何可移动介质的块设备都将使用该</font></i>
<a name='L161'><i><font color='green'>* 程序,mount/open 操作是不需要知道是否是软盘或其它什么特殊介质的。</font></i>
<a name='L162'><i><font color='green'>*/</font></i>
<a name='L163'><i><font color='green'>//// 检查磁盘是否更换,如果已更换就使对应高速缓冲区无效。</font></i>
<a name='L164'><b>void</b>
<a name='L165'><a href='../R/398.html' title='Multiple refered from 3 places.'>check_disk_change</a> (<b>int</b> dev)
<a name='L166'><font color='red'>{</font>
<a name='L167'>  <b>int</b> <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>;
<a name='L168'>
<a name='L169'><i><font color='green'>// 是软盘设备吗?如果不是则退出。</font></i>
<a name='L170'>  <b>if</b> (<a href='../S/31.html#L49' title='Defined at 49 in include/linux/fs.h.'>MAJOR</a> (<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>) != 2)
<a name='L171'>    <b>return</b>;
<a name='L172'><i><font color='green'>// 测试对应软盘是否已更换,如果没有则退出。</font></i>
<a name='L173'>  <b>if</b> (!<a href='../S/55.html#L223' title='Defined at 223 in kernel/blk_drv/floppy.c.'>floppy_change</a> (<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a> &amp; 0x03))
<a name='L174'>    <b>return</b>;
<a name='L175'><i><font color='green'>// 软盘已经更换,所以释放对应设备的i 节点位图和逻辑块位图所占的高速缓冲区;并使该设备的</font></i>
<a name='L176'><i><font color='green'>// i 节点和数据块信息所占的高速缓冲区无效。</font></i>
<a name='L177'>  <b>for</b> (<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> = 0; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a> &lt; <a href='../S/31.html#L62' title='Defined at 62 in include/linux/fs.h.'>NR_SUPER</a>; <a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>++)
<a name='L178'>    <b>if</b> (super_block[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>].s_dev == <a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>)
<a name='L179'>      <a href='../S/19.html#L108' title='Defined at 108 in fs/super.c.'>put_super</a> (super_block[<a href='../D/839.html' title='Multiple defined in 4 places.'>i</a>].s_dev);
<a name='L180'>  <a href='../S/12.html#L56' title='Defined at 56 in fs/inode.c.'>invalidate_inodes</a> (<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>);
<a name='L181'>  <a href='../S/6.html#L123' title='Defined at 123 in fs/buffer.c.'>invalidate_buffers</a> (<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>);
<a name='L182'><font color='red'>}</font>
<a name='L183'>
<a name='L184'><i><font color='green'>// hash 函数和hash 表项的计算宏定义。</font></i>
<a name='L185'><font color='darkred'>#define</font> <a href='../S/6.html#L186' title='Refered from 186 in fs/buffer.c.'>_hashfn</a>(<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>,block) (((<b>unsigned</b>)(dev^block))%<a href='../S/31.html#L63' title='Defined at 63 in include/linux/fs.h.'>NR_HASH</a>)
<a name='L186'><font color='darkred'>#define</font> <a href='../R/493.html' title='Multiple refered from 5 places.'>hash</a>(<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>,block) hash_table[<a href='../S/6.html#L185' title='Defined at 185 in fs/buffer.c.'>_hashfn</a>(dev,block)]
<a name='L187'>
<a name='L188'><i><font color='green'>//// 从hash 队列和空闲缓冲队列中移走指定的缓冲块。</font></i>
<a name='L189'><b>static</b> <b>inline</b> <b>void</b>
<a name='L190'><a href='../S/6.html#L366' title='Refered from 366 in fs/buffer.c.'>remove_from_queues</a> (<b>struct</b> buffer_head *bh)
<a name='L191'><font color='red'>{</font>
<a name='L192'><i><font color='green'>/* remove from hash-queue */</font></i>
<a name='L193'><i><font color='green'>/* 从hash 队列中移除缓冲块 */</font></i>
<a name='L194'>  <b>if</b> (bh-&gt;b_next)
<a name='L195'>    bh-&gt;b_next-&gt;b_prev = bh-&gt;b_prev;
<a name='L196'>  <b>if</b> (bh-&gt;b_prev)
<a name='L197'>    bh-&gt;b_prev-&gt;b_next = bh-&gt;b_next;
<a name='L198'><i><font color='green'>// 如果该缓冲区是该队列的头一个块,则让hash 表的对应项指向本队列中的下一个缓冲区。</font></i>
<a name='L199'>  <b>if</b> (<a href='../S/6.html#L186' title='Defined at 186 in fs/buffer.c.'>hash</a> (bh-&gt;b_dev, bh-&gt;b_blocknr) == bh)
<a name='L200'>    <a href='../S/6.html#L186' title='Defined at 186 in fs/buffer.c.'>hash</a> (bh-&gt;b_dev, bh-&gt;b_blocknr) = bh-&gt;b_next;
<a name='L201'><i><font color='green'>/* remove from free list */</font></i>
<a name='L202'><i><font color='green'>/* 从空闲缓冲区表中移除缓冲块 */</font></i>
<a name='L203'>  <b>if</b> (!(bh-&gt;b_prev_free) || !(bh-&gt;b_next_free))
<a name='L204'>    <a href='../S/72.html#L24' title='Defined at 24 in kernel/panic.c.'>panic</a> ("Free block list corrupted");
<a name='L205'>  bh-&gt;b_prev_free-&gt;b_next_free = bh-&gt;b_next_free;
<a name='L206'>  bh-&gt;b_next_free-&gt;b_prev_free = bh-&gt;b_prev_free;
<a name='L207'><i><font color='green'>// 如果空闲链表头指向本缓冲区,则让其指向下一缓冲区。</font></i>
<a name='L208'>  <b>if</b> (free_list == bh)
<a name='L209'>    free_list = bh-&gt;b_next_free;
<a name='L210'><font color='red'>}</font>
<a name='L211'>
<a name='L212'><i><font color='green'>//// 将指定缓冲区插入空闲链表尾并放入hash 队列中。</font></i>
<a name='L213'><b>static</b> <b>inline</b> <b>void</b>
<a name='L214'><a href='../S/6.html#L370' title='Refered from 370 in fs/buffer.c.'>insert_into_queues</a> (<b>struct</b> buffer_head *bh)
<a name='L215'><font color='red'>{</font>
<a name='L216'><i><font color='green'>/* put at end of free list */</font></i>
<a name='L217'><i><font color='green'>/* 放在空闲链表末尾处 */</font></i>
<a name='L218'>  bh-&gt;b_next_free = free_list;
<a name='L219'>  bh-&gt;b_prev_free = free_list-&gt;b_prev_free;
<a name='L220'>  free_list-&gt;b_prev_free-&gt;b_next_free = bh;
<a name='L221'>  free_list-&gt;b_prev_free = bh;
<a name='L222'><i><font color='green'>/* put the buffer in new hash-queue if it has a device */</font></i>
<a name='L223'><i><font color='green'>/* 如果该缓冲块对应一个设备,则将其插入新hash 队列中 */</font></i>
<a name='L224'>  bh-&gt;b_prev = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L225'>  bh-&gt;b_next = <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L226'>  <b>if</b> (!bh-&gt;b_dev)
<a name='L227'>    <b>return</b>;
<a name='L228'>  bh-&gt;b_next = <a href='../S/6.html#L186' title='Defined at 186 in fs/buffer.c.'>hash</a> (bh-&gt;b_dev, bh-&gt;b_blocknr);
<a name='L229'>  <a href='../S/6.html#L186' title='Defined at 186 in fs/buffer.c.'>hash</a> (bh-&gt;b_dev, bh-&gt;b_blocknr) = bh;
<a name='L230'>  bh-&gt;b_next-&gt;b_prev = bh;
<a name='L231'><font color='red'>}</font>
<a name='L232'>
<a name='L233'><i><font color='green'>//// 在高速缓冲中寻找给定设备和指定块的缓冲区块。</font></i>
<a name='L234'><i><font color='green'>// 如果找到则返回缓冲区块的指针,否则返回NULL。</font></i>
<a name='L235'><b>static</b> <b>struct</b> buffer_head *
<a name='L236'><a href='../R/452.html' title='Multiple refered from 2 places.'>find_buffer</a> (<b>int</b> dev, <b>int</b> block)
<a name='L237'><font color='red'>{</font>
<a name='L238'>  <b>struct</b> buffer_head *tmp;
<a name='L239'>
<a name='L240'>  <b>for</b> (tmp = <a href='../S/6.html#L186' title='Defined at 186 in fs/buffer.c.'>hash</a> (<a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a>, block); tmp != <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>; tmp = tmp-&gt;b_next)
<a name='L241'>    <b>if</b> (tmp-&gt;b_dev == <a href='../S/7.html#L136' title='Defined at 136 in fs/char_dev.c.'>dev</a> &amp;&amp; tmp-&gt;b_blocknr == block)
<a name='L242'>      <b>return</b> tmp;
<a name='L243'>  <b>return</b> <a href='../D/261.html' title='Multiple defined in 12 places.'>NULL</a>;
<a name='L244'><font color='red'>}</font>
<a name='L245'>
<a name='L246'><i><font color='green'>/*</font></i>
<a name='L247'><i><font color='green'>* Why like this, I hear you say... The reason is race-conditions.</font></i>
<a name='L248'><i><font color='green'>* As we don't lock buffers (unless we are readint them, that is),</font></i>
<a name='L249'><i><font color='green'>* something might happen to it while we sleep (ie a read-error</font></i>
<a name='L250'><i><font color='green'>* will force it bad). This shouldn't really happen currently, but</font></i>
<a name='L251'><i><font color='green'>* the code is ready.</font></i>
<a name='L252'><i><font color='green'>*/</font></i>
<a name='L253'><i><font color='green'>/*</font></i>
<a name='L254'><i><font color='green'>* 代码为什么会是这样子的?我听见你问... 原因是竞争条件。由于我们没有对</font></i>
<a name='L255'><i><font color='green'>* 缓冲区上锁(除非我们正在读取它们中的数据),那么当我们(进程)睡眠时</font></i>
<a name='L256'><i><font color='green'>* 缓冲区可能会发生一些问题(例如一个读错误将导致该缓冲区出错)。目前</font></i>
<a name='L257'><i><font color='green'>* 这种情况实际上是不会发生的,但处理的代码已经准备好了。</font></i>
<a name='L258'><i><font color='green'>*/</font></i>
<a name='L259'><i><font color='green'>////</font></i>
<a name='L260'><b>struct</b> buffer_head *
<a name='L261'><a href='../R/481.html' title='Multiple refered from 3 places.'>get_hash_table</a> (<b>int</b> dev, <b>int</b> block)
<a name='L262'><font color='red'>{</font>
<a name='L263'>  <b>struct</b> buffer_head *bh;
<a name='L264'>
<a name='L265'>  <b>for</b> (;;)
<a name='L266'>    <font color='red'>{</font>
<a name='L267'><i><font color='green'>// 在高速缓冲中寻找给定设备和指定块的缓冲区,如果没有找到则返回NULL,退出。</font></i>

⌨️ 快捷键说明

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