MIT xv6 2020系列实验:Lab9 fs

比较简单的一项实验
大索引(bigfile):
xv6的单文件索引有13个,其中只有一个二级索引,文件最大块数目是256+12 = 268块。
现在要给文件索引改成一个二级带一个三级索引,最大块数目就是11+256+256*256 = 65803块,可以容纳下很大的文件了。
先在fs.h中进行相应的更改:

...


#define FSMAGIC 0x10203040

#define NDIRECT    11
#define NDDIRECT   12
#define NINDIRECT  (BSIZE / sizeof(uint))
#define NINDDIRECT NINDIRECT * NINDIRECT
#define MAXFILE    (NDIRECT + NINDIRECT + NINDDIRECT)

// On-disk inode structure
struct dinode {

...

再在bmap中进行修改,模仿bmap中原有的索引查找方式进行索引查询即可:

...
    brelse(bp);
    return addr;
  }
/*-----------------修改线-----------------*/
  bn -= NINDIRECT;
  if (bn < NINDDIRECT) {
    // doubly-indirect block
    if((addr = ip->addrs[NDDIRECT]) == 0)
      ip->addrs[NDDIRECT] = addr = balloc(ip->dev);
    bp = bread(ip->dev, addr);
    a = (uint*)bp->data;
    if((addr = a[bn / NINDIRECT]) == 0){
      a[bn / NINDIRECT] = addr = balloc(ip->dev);
      log_write(bp);
    }
    brelse(bp);
    cp = bread(ip->dev, addr);
    b = (uint*)cp->data;
    if((addr = b[bn % NINDIRECT]) == 0){
      b[bn % NINDIRECT] = addr = balloc(ip->dev);
      log_write(cp);
    }
    brelse(cp);
    return addr;
  }

/*-----------------修改线-----------------*/

  panic("bmap: out of range");
}

这里因为bigfile太大了,make grade会超时但是单项测试是可以正常无阻塞通过的。

itrunc也类似


/*-----------------修改线-----------------*/
  if(ip->addrs[NDDIRECT]){
    bp = bread(ip->dev, ip->addrs[NDDIRECT]);
    a = (uint*)bp->data;
    for(i = 0; i < NINDIRECT; i++){
      // doubly-indirect block
      if(a[i]) {
        cp = bread(ip->dev, a[i]);
        b = (uint*)cp->data;
        for(j = 0; j < NINDIRECT; j++){
          if(b[j])
            bfree(ip->dev, b[j]);
        }
        brelse(cp);
        bfree(ip->dev, a[i]);
      }
    }
    brelse(bp);
    bfree(ip->dev, ip->addrs[NDDIRECT]);
    ip->addrs[NDDIRECT] = 0;
  }

/*-----------------修改线-----------------*/
  ip->size = 0;
  iupdate(ip);
uint64
sys_symlink(void){
  char target[MAXPATH], path[MAXPATH];
  struct inode *ip;

  if(argstr(0, target, MAXPATH) < 0 || argstr(1, path, MAXPATH) < 0)
    return -1;

  begin_op();
  if((ip = create(path, T_SYMLINK, 0, 0)) == 0){
    end_op();
    return -1;
  }
  if(writei(ip, 0, (uint64)target, 0, strlen(target) + 1) <= 0)
    panic("sys_symlink: writei");
  iunlockput(ip);
  end_op();
  return 0;
}

symlink系统调用如上。

并在sys_open中进行相应的查询:


    ilock(ip);
/*-----------------修改线-----------------*/
    if (!(omode & O_NOFOLLOW)) {
      int depth = 10;
      for (; ip->type == T_SYMLINK && depth; depth--) {
        if((ip->size > MAXPATH) || (readi(ip, 0, (uint64)path, 0, ip->size) != ip->size)){
          iunlockput(ip);
          end_op();
          return -1;
        }
        iunlockput(ip);

        if((ip = namei(path)) == 0){
          end_op();
          return -1;
        }
        ilock(ip);
      }
      if(depth == 0) {
        iunlockput(ip);
        end_op();
        return -1;
      }
    }
/*-----------------修改线-----------------*/
    if (ip->type == T_DIR && omode != O_RDONLY){
      iunlockput(ip);
      end_op();
      return -1;
    }

运行OK。





posted @   Thaudmin  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示