code:alloc - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki
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
- bp 指向 struct buf
- fp 指向 struct filsys
6961 fp = getfs(dev);
6962 while(fp->s_flock)
- 根据 设备号 得到对应的超级块
6963 sleep(&fp->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));
6971 if(fp->s_nfree <= 0) {
- 从 超级块 的空闲块数组中弹出一个 一般空闲块的块号
- 若出现以下情况,则跳转到 空间用尽错误处理 (6986)
- 空闲块数组无有效元素
- 空闲块数组弹出的块号为0(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 }
6981 bp = getblk(dev, bno);
- 若弹出空闲块块号后,空闲块数组为空,则
- 需要释放之前的管理块
- 弹出的空闲块块号 实际 指向上一个管理块
- 参看文件系统之空闲块管理
- 步骤如下
- 锁 空闲块数组
- 从磁盘读出上一个管理块
- 将上一管理块内容复制给filsys结构
- 释放磁盘缓存块
- 解锁 空闲块数组
- 唤醒所有等待使用 空闲块数组 的进程
6982 clrbuf(bp);
6983 fp->s_fmod = 1;
6984 return(bp);
6985
- 为 空闲块 申请磁盘缓存
- 将 缓存内容清零
- 置 filsys修改标志
- 返回 缓存管理块
6986 nospace:
- 以下是 空间用尽 的错误处理,处理步骤如下
- 空闲块数组的有效元素个数 置 0
- 输出错误信息
- 向用户抛出错误ENOSPC
- 返回NULL
6987 fp->s_nfree = 0;
6988 prdev("no space", dev);
6989 u.u_error = ENOSPC;
6990 return(NULL);
6991 }
6992 /*------------------------- */
6993 /*------------------------- */