231.Mit6.S081-实验九-File system

在本实验室中,您将向xv6文件系统添加大型文件和符号链接。

一、Large files

1.实验要求

在本作业中,您将增加xv6文件的最大大小。目前,xv6文件限制为268个块或268*BSIZE字节(在xv6中BSIZE为1024)。此限制来自以下事实:一个xv6 inode包含12个“直接”块号和一个“间接”块号,“一级间接”块指一个最多可容纳256个块号的块,总共12+256=268个块。

bigfile命令可以创建最长的文件,并报告其大小:

测试失败,因为bigfile希望能够创建一个包含65803个块的文件,但未修改的xv6将文件限制为268个块。

您将更改xv6文件系统代码,以支持每个inode中可包含256个一级间接块地址的“二级间接”块,每个一级间接块最多可以包含256个数据块地址。结果将是一个文件将能够包含多达65803个块,或256*256+256+11个块(11而不是12,因为我们将为二级间接块牺牲一个直接块号)。

修改bmap(),以便除了直接块和一级间接块之外,它还实现二级间接块。你只需要有11个直接块,而不是12个,为你的新的二级间接块腾出空间;不允许更改磁盘inode的大小。ip->addrs[]的前11个元素应该是直接块;第12个应该是一个一级间接块(与当前的一样);13号应该是你的新二级间接块。当bigfile写入65803个块并成功运行usertests时。

2.提示

  • 确保您理解bmap()。写出ip->addrs[]、间接块、二级间接块和它所指向的一级间接块以及数据块之间的关系图。确保您理解为什么添加二级间接块会将最大文件大小增加256*256个块(实际上要-1,因为您必须将直接块的数量减少一个)。
  • 考虑如何使用逻辑块号索引二级间接块及其指向的间接块。
  • 如果更改NDIRECT的定义,则可能必须更改file.h文件中struct inodeaddrs[]的声明。确保struct inodestruct dinode在其addrs[]数组中具有相同数量的元素。
  • 如果更改NDIRECT的定义,请确保创建一个新的fs.img,因为mkfs使用NDIRECT构建文件系统。
  • 如果您的文件系统进入坏状态,可能是由于崩溃,请删除fs.img(从Unix而不是xv6执行此操作)。make将为您构建一个新的干净文件系统映像。
  • 别忘了把你bread()的每一个块都brelse()
  • 您应该仅根据需要分配间接块和二级间接块,就像原始的bmap()
  • 确保itrunc释放文件的所有块,包括二级间接块。

3.具体实现

第一步,修改 inode 数据结构

kernel/fs.h 文件中减小 NDIRECT 的值,并添加宏定义

(2). 由于NDIRECT定义改变,其中一个直接块变为了二级间接块,需要修改inode结构体中addrs元素数量

上面的是磁盘中的 inode 结构,还需要在 kernel/file.h 中更改内存中的 inode 结构:

(3). 修改bmap支持二级索引,仿照一级索引,写一下二级索引,在 kernel/fs.c 中添加代码:

(4). 在 kernel/fs.c 中,添加第二级索引的释放操作:

4.测试结果

二、Symbolic links

1.实验要求

在本练习中,您将向xv6添加符号链接。符号链接(或软链接)是指按路径名链接的文件;当一个符号链接打开时,内核跟随该链接指向引用的文件。符号链接类似于硬链接,但硬链接仅限于指向同一磁盘上的文件,而符号链接可以跨磁盘设备。尽管xv6不支持多个设备,但实现此系统调用是了解路径名查找工作原理的一个很好的练习。

您将实现symlink(char *target, char *path)系统调用,该调用在引用由target命名的文件的路径处创建一个新的符号链接。有关更多信息,请参阅symlink手册页(注:执行man symlink)。要进行测试,请将symlinktest添加到Makefile并运行它。当测试产生以下输出(包括usertests运行成功)时,您就完成本作业了。

2.提示

  • 首先,为symlink创建一个新的系统调用号,在user/usys.pluser/user.h中添加一个条目,并在kernel/sysfile.c中实现一个空的sys_symlink
  • kernel/stat.h添加新的文件类型(T_SYMLINK)以表示符号链接。
  • 在kernel/fcntl.h中添加一个新标志(O_NOFOLLOW),该标志可用于open系统调用。请注意,传递给open的标志使用按位或运算符组合,因此新标志不应与任何现有标志重叠。一旦将user/symlinktest.c添加到Makefile中,您就可以编译它。
  • 实现symlink(target, path)系统调用,以在path处创建一个新的指向target的符号链接。请注意,系统调用的成功不需要target已经存在。您需要选择存储符号链接目标路径的位置,例如在inode的数据块中。symlink应返回一个表示成功(0)或失败(-1)的整数,类似于linkunlink
  • 修改open系统调用以处理路径指向符号链接的情况。如果文件不存在,则打开必须失败。当进程向open传递O_NOFOLLOW标志时,open应打开符号链接(而不是跟随符号链接)。
  • 如果链接文件也是符号链接,则必须递归地跟随它,直到到达非链接文件为止。如果链接形成循环,则必须返回错误代码。你可以通过以下方式估算存在循环:通过在链接深度达到某个阈值(例如10)时返回错误代码。
  • 其他系统调用(如linkunlink)不得跟随符号链接;这些系统调用对符号链接本身进行操作。
  • 您不必处理指向此实验的目录的符号链接。

3.具体实现

(1)增加 symlink 系统调用

user/usys.pl

user/user.h

kernel/syscall.h

kernel/syscall.c

(2). 添加提示中的相关定义,T_SYMLINK以及O_NOFOLLOW

// fcntl.h
#define O_NOFOLLOW 0x004
// stat.h
#define T_SYMLINK 4

(3). 在kernel/sysfile.c中实现sys_symlink,这里需要注意的是create返回已加锁的inode,此外iunlockput既对inode解锁,还将其引用计数减1,计数为0时回收此inode

uint64 
sys_symlink(void)
{ 
  char target[MAXPATH]; 缓冲区,用于存储目标路径
  char path[MAXPATH];  // 缓冲区,用于存储路径
  // 用来接收 create 函数返回的 inode
  struct inode *ip_path;

  // 通过用户态获取目标路径字符串,并将其复制到 target 缓冲区
  if(argstr(0, target, MAXPATH)<0)
  {
    return -1;
  }

  // 通过用户态获取链接路径字符串,并将其复制到 path 缓冲区
  if(argstr(1, path, MAXPATH)<0)
  {
    return -1;
  }
  begin_op();  // 启动文件系统操作
  // 先找,如果不存在就创建一个类型为 T_SYMLINK 的 inode 节点,分配一个新的 i 节点并返回指向它的指针,如果成功
  ip_path = create(path, T_SYMLINK, 0, 0);
  if(ip_path==0)
  {
    end_op();// 取消文件系统操作
    return -1;
  }
  // 向新创建的 ip_path 指定的 i 节点写入 MAXPATH 大小的数据
  if(writei(ip_path,0,(uint64)target,0,MAXPATH)<MAXPATH)
  {
    // 释放指向新 i 节点的指针,并将其计数器减一,如果计数器变为 0,则释放 i 节点和相关资源
    iunlockput(ip_path);
    end_op();
    return -1;
  }

  // 释放指向新 i 节点的指针,并将其计数器减一,如果计数器变为 0,则释放 i 节点和相关资源
  iunlockput(ip_path);
  end_op();// 取消文件系统操作
  return 0;// 返回 0 表示成功
}

(4). 修改sys_open支持打开符号链接

4.测试结果

  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清酒。233

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值