Yra's blog Yra's blog
Homepage
  • LeetCode周赛
  • Acwing周赛
  • 刷题整理
  • 题解
  • CPP
  • Golang
  • System

    • MIT6.S081 Labs
  • Computer Networking

    • CS144: Computer Networking
  • DataBase

    • MySQL
    • Redis
  • Others

    • ......
  • Paper Reading

    • Petri Net
  • Static Analysis

    • NJU Course Notes
  • Deep Learning

    • Dive into Deep Learning
Casual Records
Archives

Yra

Only a vegetable dog.
Homepage
  • LeetCode周赛
  • Acwing周赛
  • 刷题整理
  • 题解
  • CPP
  • Golang
  • System

    • MIT6.S081 Labs
  • Computer Networking

    • CS144: Computer Networking
  • DataBase

    • MySQL
    • Redis
  • Others

    • ......
  • Paper Reading

    • Petri Net
  • Static Analysis

    • NJU Course Notes
  • Deep Learning

    • Dive into Deep Learning
Casual Records
Archives
  • System

    • MIT6.S081 | 21Fall

      • Lab1: Unix utilities
      • Lab2: System Calls
      • Lab3: Page Tables
      • Lab4: Traps
      • Lab5: Copy-on-Write Fork for xv6
      • Lab6: Multithreading
      • Lab7: Networking
      • Lab8: Locks
      • Lab9: File System
        • Symbolic links
          • 实验结果
      • Lab10: Mmap
  • Computer Networking

  • DataBase

  • Software Engineering

  • Others

  • Learning Notes
  • System
  • MIT6.S081 | 21Fall
Yra
2023-02-23
目录

[MIT6.S081]Lab9: File System

# [MIT6.S081]Lab9: File System

Lab: file system (mit.edu) (opens new window)

# Large files

在这个 assignment 中我们要扩充 xv6 文件的大小从 268 个块到 65803 个块,一开始我们的 inode 存储了 12 个 direct 的块号,以及一个 singly-indirect 块号 (类似于页表的多级映射,这里是单级)。每个 singly-indirect 块号代表了一个包含了 256 个块号的块。我们通过拿掉一个 direct 的块号,添加一个 doubly-indirect 块号(二级映射),而一个 doubly-indirect 块号代表了一个包含 256 个 singly-indirect 块号的块。

如此一来我们最后的块个数是 (12 - 1) * 1 + 256 + 256 * 256 = 65803

首先我们修改一些宏定义和数组长度

// fs.h
#define NDIRECT 11

// On-disk inode structure
struct dinode {
// ......
  uint addrs[NDIRECT+2];   // Data block addresses
};

// file.h
struct inode {
// ......
  uint addrs[NDIRECT+2];
};

接着我们先修改 bmap() 函数

如果他不在一级索引的范围内,那么我们可以像前面一样给块号减去一个 NINDIRECT,有助于我们后面直接判断二级索引的范围是 < NINDIRECT * NINDIRECT。

接下里的部分很前面类似,只是要映射两次,需要注意的是对于第一层的索引,我们的块号取得是 nb / NINDIRECT,而第二层的索引是 bn % NINDIRECT。

if(bn < NINDIRECT) { // 一级索引的范围
    // Load indirect block, allocating if necessary.
    if((addr = ip->addrs[NDIRECT]) == 0)
      ip->addrs[NDIRECT] = addr = balloc(ip->dev);
    bp = bread(ip->dev, addr);
    a = (uint*)bp->data; // 一级索引
    if((addr = a[bn]) == 0) {
      a[bn] = addr = balloc(ip->dev);
      log_write(bp);
    }
    brelse(bp);
    return addr;
  }
  bn -= NINDIRECT;

  if(bn < NINDIRECT * NINDIRECT) { // 二级索引的范围
    if((addr = ip->addrs[NDIRECT + 1]) == 0)
      ip->addrs[NDIRECT + 1] = addr = balloc(ip->dev);
    bp = bread(ip->dev, addr);
    a = (uint *)bp->data; // 二级索引的第一级
    if ((addr = a[bn / NINDIRECT]) == 0) { // bn / NINDIRECT 是第一级的 index
      a[bn / NINDIRECT] = addr = balloc(ip->dev);
      log_write(bp);
    }
    brelse(bp); // 释放锁
    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); // 释放锁

    return addr;
  }

最后我们还要修改 itrunc() 函数,同样十分类似,只是多嵌套了一层映射,另外要注意 NDIRECT 和 NINDIRECT 不要用错。

  if (ip->addrs[NDIRECT + 1]) {// 二级索引
    bp = bread(ip->dev, ip->addrs[NDIRECT + 1]);
    a = (uint *)bp->data; // 一级 index
    for (int i = 0; i < NINDIRECT; i++) {
      if (a[i]) {
        bp2 = bread(ip->dev, a[i]); // 二级 index
        uint *b = (uint *)bp2->data; 
        for (int j = 0; j < NINDIRECT; j++) {
          if (b[j]) {
            bfree(ip->dev, b[j]);
          }
        }
        brelse(bp2);
        bfree(ip->dev, a[i]);
      }
    }
    brelse(bp);
    bfree(ip->dev, ip->addrs[NDIRECT + 1]);
    ip->addrs[NDIRECT + 1] = 0;
  }

# Symbolic links

在这个 assignment 中要为 xv6 添加软连接,实现 symlink 的系统调用。

添加系统调用过程不再赘述,具体的实现部分参考其他函数和手册给出的 hints 一步步实现即可。

// sysfile.c
uint64 sys_symlink(void) {
  struct inode *ip;
  char target[MAXPATH];
  char path[MAXPATH];

  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, MAXPATH) < 0) { // 存储路径
    end_op();
    return -1;
  }
  iunlockput(ip);
  end_op();
  return 0;
}

uint64
sys_open(void)
{
  char path[MAXPATH];
  int fd, omode;
  struct file *f;
  struct inode *ip;
  int n;

  if((n = argstr(0, path, MAXPATH)) < 0 || argint(1, &omode) < 0)
    return -1;

  begin_op();

  if(omode & O_CREATE){
    ip = create(path, T_FILE, 0, 0);
    if(ip == 0){
      end_op();
      return -1;
    }
  } else {
    if((ip = namei(path)) == 0){
      end_op();
      return -1;
    }
    ilock(ip);
    if(ip->type == T_DIR && omode != O_RDONLY){
      iunlockput(ip);
      end_op();
      return -1;
    }
  }

  if(ip->type == T_DEVICE && (ip->major < 0 || ip->major >= NDEV)){
    iunlockput(ip);
    end_op();
    return -1;
  }
  if ((ip->type == T_SYMLINK) && ((omode & O_NOFOLLOW) == 0)) {
    int cnt = 0;
    char target[MAXPATH];
    while (1) {
      if (++cnt > 10) {
        iunlockput(ip);
        end_op();
        return -1;
      }
      if (ip->type != T_SYMLINK) { // 如果不是 symlink 了九条出去
        break;
      }
      readi(ip, 0, (uint64)target, 0, MAXPATH); // 从 ip 中读取数据(路径名)
      iunlockput(ip);
      if ((ip = namei(target)) == 0) { // 找不到文件
        end_op();
        return -1;
      }
      ilock(ip);
    }
  }

  if((f = filealloc()) == 0 || (fd = fdalloc(f)) < 0){
    if(f)
      fileclose(f);
    iunlockput(ip);
    end_op();
    return -1;
  }

  if(ip->type == T_DEVICE){
    f->type = FD_DEVICE;
    f->major = ip->major;
  } else {
    f->type = FD_INODE;
    f->off = 0;
  }
  f->ip = ip;
  f->readable = !(omode & O_WRONLY);
  f->writable = (omode & O_WRONLY) || (omode & O_RDWR);

  if((omode & O_TRUNC) && ip->type == T_FILE){
    itrunc(ip);
  }

  iunlock(ip);
  end_op();

  return fd;
}

# 实验结果


image-20230223225722434
image-20230224010933081
#Learning Notes#System#6.S081
Last Updated: 3/4/2023, 5:38:14 PM
Lab8: Locks
Lab10: Mmap

← Lab8: Locks Lab10: Mmap→

最近更新
01
408 计组笔记
07-19
02
Dive into Deep Learning
01-27
03
25 考研随记
11-27
更多文章>
Theme by Vdoing | Copyright © 2022-2025
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式