code:breada - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki

Table of Contents

Source

  • 从指定设备,读取块并预读块
  • 共传入三个参数 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);

  • 在指定设备的设备队列中 查找匹配 blkno 的缓存块 (incore)
  • 如找不到,则调用 getblk 申请可用缓存块
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);

  • 置 B_READ 标志,置传输字节数
  • 启动 设备驱动进行I/O
  • 在此不等待I/O结束,而是在函数末尾调用 iowait等待I/O,以提高效率
4786          }

4787     }

  • 以下进行预读块处理
4788     if (rablkno && !incore(dev, rablkno)) {

4789          rabp = getblk(dev, rablkno);

  • 在指定设备的设备队列中 查找匹配 rablkno 的缓存块 (incore)
  • 如找不到,则调用 getblk 申请可用缓存块
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          }

  • 置 B_READ B_ASYNC 标志,置传输字节数
  • 启动 设备驱动进行异步I/O
  • 由于预读块是异步I/O,在此不等待I/O结束
4797     }

4798     if (rbp==0)

4799          return(bread(dev, blkno));

  • 若rbp == 0 ,说明直接从 指定设备设备队列中找到了读取块的缓存
  • 调用bread读出此缓存
4800     iowait(rbp);

4801     return(rbp);

  • 否则,等待读取块 I/O结束,返回块缓存
4802 }

4803 /* ------------------------- */

Extend

讨论

  • 以下是关于4782行,4790 - 4791行的讨论
  • 以4782行为例
4780行调用incore,已经完成了getblk中查找现成缓存块的工作(4937 - 4950)
所以4781调用getblk的作用仅是申请缓存块
那么4782的判断显得有些多余,因为申请的缓存块不可能置B_DONE标志
4790 - 4791行结论类似
  • 第二种观点认为
incoregetblk之间可能存在 I/O中断(比如I/O完成),释放了缓存块,所以才由4782进行判断
但这种可能性存在可能性很小,比起每次都进行4782的判断,显得开销入不敷出

附图

Ref

Caller

⚠️ **GitHub.com Fallback** ⚠️