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

Source

  • 获取 指定磁盘的空闲块,参看文件系统
  • 共传入1个参数 dev
    • dev : 磁盘的设备号
  • 返回值
    • 空闲块的缓存管理块,参看设备缓存管理
    • 若磁盘空间用尽,则抛出错误,返回NULL

6944

6945 /*

6946  * alloc will obtain the next available

6947  * free disk block from the free list of

6948  * the specified device.

6949  * The super block has up to 100 remembered

6950  * free blocks; the last of these is read to

6951  * obtain 100 more . . .

6952  *

6953  * no space on dev x/y -- when

6954  * the free list is exhausted.

6955  */

6956 alloc(dev)

6957 {

6958     int bno;

6959     register *bp, *ip, *fp;

6960

6961     fp = getfs(dev);

  • 根据 设备号 得到对应的超级块
6962     while(fp->s_flock)

6963          sleep(&fp->s_flock, PINOD);

  • 若 超级块的空闲块数组 被置锁,则睡眠
  • 直到 超级块的空闲块数组 可用
  • 睡眠原因 : filsys.s_flock
  • 睡眠优先级 : PINOD
6964     do {

6965          if(fp->s_nfree <= 0)

6966           goto nospace;

6967          bno = fp->s_free[--fp->s_nfree];

6968          if(bno == 0)

6969           goto nospace;

6970     } while (badblock(fp, bno, dev));

  • 从 超级块 的空闲块数组中弹出一个 一般空闲块的块号
  • 若出现以下情况,则跳转到 空间用尽错误处理 (6986)
    • 空闲块数组无有效元素
    • 空闲块数组弹出的块号为0(0是空间用尽标志,参看文件系统)
6971     if(fp->s_nfree <= 0) {

6972          fp->s_flock++;

6973          bp = bread(dev, bno);

6974          ip = bp->b_addr;

6975          fp->s_nfree = *ip++;

6976          bcopy(ip, fp->s_free, 100);

6977          brelse(bp);

6978          fp->s_flock = 0;

6979          wakeup(&fp->s_flock);

6980     }

  • 若弹出空闲块块号后,空闲块数组为空,则
  • 步骤如下
    • 锁 空闲块数组
    • 从磁盘读出上一个管理块
    • 将上一管理块内容复制给filsys结构
    • 释放磁盘缓存块
    • 解锁 空闲块数组
    • 唤醒所有等待使用 空闲块数组 的进程
6981     bp = getblk(dev, bno);

6982     clrbuf(bp);

6983     fp->s_fmod = 1;

6984     return(bp);

  • 为 空闲块 申请磁盘缓存
  • 将 缓存内容清零
  • 置 filsys修改标志
  • 返回 缓存管理块
6985
  • 以下是 空间用尽 的错误处理,处理步骤如下
    • 空闲块数组的有效元素个数 置 0
    • 输出错误信息
    • 向用户抛出错误ENOSPC
    • 返回NULL
6986 nospace:

6987     fp->s_nfree = 0;

6988     prdev("no space", dev);

6989     u.u_error = ENOSPC;

6990     return(NULL);

6991 }

6992 /*------------------------- */

6993 /*------------------------- */

Ref

Caller

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