code:getblk - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki
- 寻找 与指定设备指定块号匹配的缓存块
- 共传入两个参数 dev , blkno
- dev 指定设备号
- blkno 指定块号
- getblk的第二功能(与设备IO无关)
- 可以为程序提供512字节长的缓存区
- 为避免错误,此时设备为NODEV
- 此时传入参数 dev 为负
4914 /* Assign a buffer for the given block. If the appropriate
4915 * block is already associated, return it; otherwise search
4916 * for the oldest non-busy buffer and reassign it.
4917 * When a 512-byte area is wanted for some random reason
4918 * (e.g. during exec, for the user arglist) getblk can be
4919 * called with device NODEV to avoid unwanted associativity.
4920 */
4921 getblk(dev, blkno)
4922 {
4923 register struct buf *bp;
4924 register struct devtab *dp;
4925 extern lbolt;
4926
- 关于lbolt,参见遗留问题
4927 if(dev.d_major >= nblkdev)
4928 panic("blkdev");
4929
- 如果外设主设备号越界,则执行panic,进行出错处理
4930 loop:
4931 if (dev < 0)
4932 dp = &bfreelist;
4933 else {
- 若dev为负数
- 则将dp指向 NODEV设备 的设备控制结构
- 此时 getblk 发挥第二功能
4934 dp = bdevsw[dev.d_major].d_tab;
4935 if(dp == NULL)
4936 panic("devtab");
4937 for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) {
4938 if (bp->b_blkno!=blkno || bp->b_dev!=dev)
4939 continue;
4940 spl6();
- 遍历设备队列,查找与设备号dev和块号blkno匹配的缓存块
4941 if (bp->b_flags&B_BUSY) {
- 处理机优先级设为6,防止不必要的中断进入
4942 bp->b_flags =| B_WANTED;
4943 sleep(bp, PRIBIO);
4944 spl0();
4945 goto loop;
4946 }
4947 spl0();
4948 notavail(bp);
4949 return(bp);
4950 }
4951 }
4952 spl6();
4953 if (bfreelist.av_forw == &bfreelist) {
4954 bfreelist.b_flags =| B_WANTED;
4955 sleep(&bfreelist, PRIBIO);
4956 spl0();
4957 goto loop;
4958 }
4959 spl0();
4960 notavail(bp = bfreelist.av_forw);
4961 if (bp->b_flags & B_DELWRI) {
4962 bp->b_flags =| B_ASYNC;
4963 bwrite(bp);
4964 goto loop;
4965 }
4966 bp->b_flags = B_BUSY | B_RELOC;
4967 bp->b_back->b_forw = bp->b_forw;
4968 bp->b_forw->b_back = bp->b_back;
4969 bp->b_forw = dp->b_forw;
- 若不含B_DELWRI,b_flags置为B_BUSY
- B_RELOC标志为 UNIX 源代码写作时的遗留,已经无作用 (引自Lions源代码分析)
- 将该缓存块从原设备队列中取出
4970 bp->b_back = dp;
4971 dp->b_forw->b_back = bp;
4972 dp->b_forw = bp;
4973 bp->b_dev = dev;
- 将该缓存块插入新的设备队列队首
4974 bp->b_blkno = blkno;
4975 return(bp);
4976 }
- 设置缓存块的设备号与块号
- 返回指向该缓存管理块的指针bp
4977 /* ------------------------- */