code:breada - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki
- 从指定设备,读取块并预读块
- 共传入三个参数 adev blkno rablkno
- adev : 指定设备号
- blkno : 读取块的块号
- rablkno : 预读块的块号
4768
4769 /*
4770 * Read in the block, like bread, but also start I/O on the
4771 * read-ahead block (which is not allocated to the caller)
4772 */
4773 breada(adev, blkno, rablkno)
4774 {
4775 register struct buf *rbp, *rabp;
4776 register int dev;
4777
4778 dev = adev;
4779 rbp = 0;
4780 if (!incore(dev, blkno)) {
4781 rbp = getblk(dev, blkno);
4782 if ((rbp->b_flags&B_DONE) == 0) {
4783 rbp->b_flags =| B_READ;
- 此处参看 讨论
4784 rbp->b_wcount = -256;
4785 (*bdevsw[adev.d_major].d_strategy)(rbp);
4786 }
- 置 B_READ 标志,置传输字节数
- 启动 设备驱动进行I/O
- 在此不等待I/O结束,而是在函数末尾调用 iowait等待I/O,以提高效率
4787 }
4788 if (rablkno && !incore(dev, rablkno)) {
- 以下进行预读块处理
4789 rabp = getblk(dev, rablkno);
4790 if (rabp->b_flags & B_DONE)
4791 brelse(rabp);
4792 else {
- 此处参看 讨论
4793 rabp->b_flags =|B_READ|B_ASYNC;
4794 rabp->b_wcount = -256;
4795 (*bdevsw[adev.d_major].d_strategy)(rabp);
4796 }
4797 }
- 置 B_READ B_ASYNC 标志,置传输字节数
- 启动 设备驱动进行异步I/O
- 由于预读块是异步I/O,在此不等待I/O结束
4798 if (rbp==0)
4799 return(bread(dev, blkno));
4800 iowait(rbp);
4801 return(rbp);
4802 }
- 否则,等待读取块 I/O结束,返回块缓存
4803 /* ------------------------- */
- 以下是关于4782行,4790 - 4791行的讨论
- 以4782行为例
- 4780行调用incore,已经完成了getblk中查找现成缓存块的工作(4937 - 4950)
- 所以4781调用getblk的作用仅是申请缓存块
- 那么4782的判断显得有些多余,因为申请的缓存块不可能置B_DONE标志
- 4790 - 4791行结论类似
- 第二种观点认为
- 此处被列入遗留问题