6.s081 学习实验记录(十)file system

文章目录

    • 一、Large files
      • 简介
      • 提示
      • 实验代码
      • 实验结果
    • 二、Symbolic links
      • 简介
      • 提示
      • 实验代码
      • 实验结果

首先切换到 fs 分支

  • $ git fetch
  • $ git checkout fs
  • $ make clean

一、Large files

简介

该实验需要我们增大xv6文件的最大大小,目前xv6的最大文件大小为 268个块,即 268 * BSIZE。这是因为 xv6 包含12个直接块号 和 一个一级间接块号最大索引 12 + 256 = 268 个块

bigfile 命令将创建xv6允许的最大文件,并报告其大小,未进行实验前结果如图:
在这里插入图片描述
我们需要让xv6支持二级间接块,这样支持的索引块号最大为 11 + 256 + 256 * 256 = 65803 个,这样即可满足 bigfile 的测试要求。

我们的任务:修改 bmap() 函数让其可以支持二重间接块号,

提示

  • 磁盘文件的inode定义由 fs.hstruct inode 定义
  • 主目录中的 mkfs 程序用于创建 xv6 文件系统磁盘硬件并确定该磁盘总共多少数据块,磁盘的总大小由 kernel/param.h 中的FSSIZE 控制,当前分支已经将磁盘的大小改为 20w 个块大小
  • 在磁盘上查找文件数据的函数是 fs.cbmap(),阅读它并确保知道该函数在做什么。该函数在读取和写入文件时都会被调用,写入时bmap()根据需要分配新的块来保存内容,并根据需要分配间接块来保存块地址。
  • 可以将 bmap() 函数理解为将文件的逻辑块号映射为磁盘的物理块号,该函数的 bn 参数表示逻辑块号。而 ip->addrs[] 数组下标和 bread() 需要的都是物理块号,因此 bmap() 需要将 bn 转换为物理块号
  • 如果修改NDIRECT的定义,应该同时修改 file.hstruct inodeaddrs[]数组的大小,需要让他们保证元素数目一致
  • 不要忘记在 bread() 后对读取的块使用 brelse() 函数
  • 确保 itrunc() 可以释放所有块,包括二级间接块

实验代码

本实验中磁盘的最大已经改为20w,因此无需通过mkfs重新创建磁盘。我们只需要修改bmap()即可。

  • fs.h
#define NDIRECT 11
#define ONE_LEVEL_INDIRECT_IDX 11
#define TWO_LEVEL_INDIRECT_IDX 12
#define NINDIRECT (BSIZE / sizeof(uint))
#define N_TWO_INDIRECT NINDIRECT * NINDIRECT
#define MAXFILE (NDIRECT + NINDIRECT + N_TWO_INDIRECT)// On-disk inode structure
struct dinode {short type;           // File typeshort major;          // Major device number (T_DEVICE only)short minor;          // Minor device number (T_DEVICE only)short nlink;          // Number of links to inode in file systemuint size;            // Size of file (bytes)uint addrs[NDIRECT+2];   // Data block addresses
};
  • fs.c
struct {struct spinlock lock;struct inode inode[TWO_LEVEL_INDIRECT_IDX];
} itable;static uint
bmap(struct inode *ip, uint bn)
{uint addr, *a;struct buf *bp;// 如果是直接块if(bn < NDIRECT){if((addr = ip->addrs[bn]) == 0)ip->addrs[bn] = addr = balloc(ip->dev);return addr;}bn -= NDIRECT;// 如果属于一级间接块的范围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 < N_TWO_INDIRECT){// 加载二级间接索引块,如果二级索引块还未分配,则分配一个数据块作为二级索引块// 如果二级索引块不存在,为其分配地址,并记录在 addrs 数组对应的位置if((addr = ip->addrs[TWO_LEVEL_INDIRECT_IDX]) == 0){ip->addrs[TWO_LEVEL_INDIRECT_IDX] = addr = balloc(ip->dev);}// 读取二级索引块,内容为一级索引块地址bp = bread(ip->dev, addr);a = (uint*)bp->data;// bn 必定是可以整除 NINDIRECT 的数,决定查询一级索引的第几项,如果此时一级索引块也未分配// 分配一级索引块,并将地址记录到对应的二级索引块中if((addr = a[bn / NINDIRECT]) == 0){a[bn / NINDIRECT] = addr = balloc(ip->dev);log_write(bp);}brelse(bp);// 读取一级索引块的内容bp = bread(ip->dev, addr);a = (uint*)bp->data;// 得到在一级索引块中实际数据块的idx,如果不存在,则分配if((addr = a[bn % NINDIRECT]) == 0){a[bn % NINDIRECT] = addr = balloc(ip->dev);log_write(bp);}brelse(bp);return addr;}panic("bmap: out of range");
}

实验结果

  • usertests -q(该程序至少需要运行1分半)
    在这里插入图片描述
  • userstest -q
    在这里插入图片描述

二、Symbolic links

简介

实现符号链接(软链接)
目标:实现 symlink(char *target, char *path) 系统调用,该系统调用在path表示路径下创建一个新的符号链接,引用target路径。最终通过symlinktest测试。

提示

  • 创建一个新的系统调用 symlink,在 user/usys.pl, user/user.h添加对应的项,在 kernel/sysfile.c 中实现sys_symlink()函数
  • kernel/stat.h 中添加T_SYMLINK文件类型,表示符号链接类型的文件
  • kernel/fcntl.h添加一个新的flag标志位O_NOFOLLOW,该标记位将在 open() 系统调用中使用。注意flag标记位在open() 中使用时需要使用按位或(or)
  • 实现 symlink 系统调用的逻辑,需要在一个地方先缓存 target 路径,可以选择存储在 inode的数据块中,同时该系统调用应该在成功时返回0,失败时返回-1
  • 修改 open()系统调用,在打开一个符号链接文件时,如果其引用的对象不存在,则打开失败,如果存在,则打开其引用的对象
  • 如果符号链接文件引用的文件依然是符号链接文件,那么需要递归的去引用,直到遇到一个非链接文件。如果递归变为循环递归,需要返回错误,且需要添加一个递归阈值(例如10)以防止无限制递归。
  • 其他系统调用,操作符号链接文件本身时,就应该操作该文件本身(例如 link、unlink)。
  • 无需处理对于目录的符号链接

实验代码

  • kernel/fcntl.h
#define O_NOFOLLOW 0x004
  • kernel/stat.h
#define T_SYMLINK  4  // symbol link
  • user/user.h
int symlink(char *target, char *path);
  • user/usys.pl
entry("symlink");
  • makefile
$U/_symlinktest\
  • kernel/syscall.h
#define SYS_symlink  22
  • kernel/syscall.c
extern uint64 sys_symlink(void);static uint64 (*syscalls[])(void) = {
// ...
[SYS_close]   sys_close,
[SYS_symlink] sys_symlink,
};
  • kernel/sysfile.c:sys_symlink 可以参考 sys_link
uint64
sys_symlink(void){char target[MAXPATH];char path[MAXPATH];struct inode *ip;if((argstr(0, target, MAXPATH)) < 0 || argstr(1, path, MAXPATH) < 0)return -1;begin_op();// 如果是目录,返回错误if((ip = namei(target)) != 0){ilock(ip);if(ip->type == T_DIR){iunlock(ip);end_op();return -1;}iunlock(ip);}// 创建软链接文件,返回的是一个上锁的fdip = create(path, T_SYMLINK, 0, 0);if(ip == 0){end_op();return -1;}// 将 target 路径写入到软链接文件中if(writei(ip, 0, (uint64)target, 0, strlen(target) + 1) <= 0) {end_op();return -1;}iunlockput(ip);end_op();return 0;
}
  • kernel/sysfile.c:修改 sys_open(),添加对于软链接文件的处理
uint64
sys_open(void){// ...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_SYMLINK && !(omode & O_NOFOLLOW)) {int total = 10;while (ip->type == T_SYMLINK && total > 0) {// 读取软链接文件中存储的 target 路径if(readi(ip, 0, (uint64)path, 0, ip->size) != ip->size) {iunlockput(ip);end_op();return -1;}iunlockput(ip); //释放软链接文件的锁// ip重新赋值为软链接 target 指向的文件if((ip = namei(path)) == 0) {end_op();return -1;}// 锁住,进行下一轮判断ilock(ip);total--;}// 超过循环上限if (total == 0) {iunlockput(ip);end_op();return -1;}}}// ... 其他代码
}

实验结果

  • symlinktest
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/688611.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WordPress主题YIA在广告位添加图片广告时下方有空白怎么办?

YIA主题设置中默认有4个广告位&#xff0c;而侧边栏的广告位由站长自行添加。boke112百科在这些广告位添加图片广告后发现图片下方有空白&#xff0c;导致下方的两个角没有变圆角&#xff0c;看起来也有点不好看。具体如下图所示&#xff1a; 其实&#xff0c;这个问题就是典型…

挑战杯 地铁大数据客流分析系统 设计与实现

文章目录 1 前言1.1 实现目的 2 数据集2.2 数据集概况2.3 数据字段 3 实现效果3.1 地铁数据整体概况3.2 平均指标3.3 地铁2018年9月开通运营的线路3.4 客流量相关统计3.4.1 线路客流量排行3.4.2 站点客流量排行3.4.3 入站客流排行3.4.4 整体客流随时间变化趋势3.4.5 不同线路客…

跟着pink老师前端入门教程(JavaScript)-day01

一、计算机编程基础 &#xff08;一&#xff09;编程语言 1、编程 编程&#xff1a;就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码&#xff0c;并最终得到结果的过程。 计算机程序&#xff1a;就是计算机所执行的一系列的指令集合&#xff0c;而程序全部…

嵌入式学习 C++ Day5、6

嵌入式学习 C Day5、6 一、思维导图 二、作业 1.以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴…

UVa1359/LA3491 Hills

题目链接 本题是2005年ICPC亚洲区域赛杭州欧赛区的H题 题意 平面上有 n&#xff08;n≤500&#xff09;条线段&#xff0c;其中每条线段的端点都不会在其他线段上。你的任务是数一数有多少个“没有被其他线段切到”的三角形&#xff08;即小山&#xff09;。如下图所示&#x…

【Vitis】Vitis性能优化的开源库

Vitis HLS简介 Vitis™HLS是一种高层次综合工具&#xff0c;支持将C、C和OpenCL™函数硬连线到器件逻辑互连结构和RAM/DSP块上。 Vitis HLS可在Vitis应用加速开发流程中实现硬件内核&#xff0c;并使用C/C语言代码在VivadoDesign Suite中为赛灵思器件设计开发RTL IP。 【Vitis…

sqlserver 分组查询

在 SQL Server 中&#xff0c;分组查询是指使用 GROUP BY 子句对查询结果进行分组&#xff0c;并对每个组应用聚合函数&#xff08;如 SUM、COUNT、AVG 等&#xff09;以计算每个组的汇总值。 以下是一个基本的分组查询示例&#xff1a; SELECT 列1, 列2, 聚合函数(列3) FROM…

不坑盒子 助力高效办公的Office插件

不坑盒子简介 很多朋友在工作过程中需要对Word文档进行编辑处理&#xff0c;如果想让Word排版更有效率可以试试小编带来的这款不坑盒子软件&#xff0c;是一个非常好用的办公工具&#xff0c;拥有近百项功能的Word&#xff0c;wps插件&#xff0c;支持Office 2010以上的版本&a…

【plt.bar绘制条形图or柱状图】:从入门到精通,只需一篇文章!【Matplotlib可视化】

【&#x1f4ca;plt.bar绘制条形图】&#xff1a;从入门到精通&#xff0c;只需一篇文章&#xff01;【Matplotlib】 利用Matplotlib进行数据可视化示例 &#x1f335;文章目录&#x1f335; &#x1f50d; 一、初识plt.bar&#xff1a;条形图的基本概念&#x1f4a1; 二、plt.…

Maven - Plugins报错的正确解决之道

背景&#xff1a; 正确解决之道&#xff1a; 在自己本地Maven的安装目录中找到自己的仓库地址目录&#xff1a;直接搜索自己报错的插件文件&#xff0c;把它们删除&#xff0c;如图&#xff1a; 接着回到IDEA点击Maven刷新按钮重新加载即可&#xff1a;已解决 反例&#xff1…

使用pycaw检测微信消息提示

使用pycaw检测微信消息提示 利用pywinauto库&#xff0c;我们确实可以实现在社交软件上的自动接收与发送消息功能。但要精确捕捉新消息的到达时机&#xff0c;这一库显得稍显笨拙。 这种方法虽然实用&#xff0c;但在效率上可能不是最优选择。 新消息的来到不仅仅有消息记录的…

Swagger-的使用

Swagger-的使用 前言效果1、相关依赖2、相关注解2.1 @Tag设置整个类的名称和详情2.2 @Operation描述具体的方法2.3 @Parameter 描述参数2.4@Schema 为属性添加注释3、Docket配置3.1通过gropeediopenapi进行分组3.2 通过docsOpenApi设置前言 在我们和前端进行交互的时候,出接口…

【机构vip教程】Appium自动化(2):Python+Appium环境搭建

windows下搭建pythonappium环境 搭建过程步骤如下&#xff1a; 1、安装jdk并配置好环境变量&#xff08;jdk版本1.8以上&#xff09; 2、安装android-sdk并配置好环境变量&#xff1b;具体步骤见&#xff1a;https://www.cnblogs.com/YouJeffrey/p/15243705.html 3、安装安…

浅谈js事件机制

事件是什么&#xff1f;事件模型&#xff1f; 原始事件模型&#xff08;DOM0级&#xff09; HTML代码中指定属性值&#xff1a;在js代码中指定属性值&#xff1a;优点&#xff1a;缺点&#xff1a; IE 事件模型DOM2事件模型 对事件循环的理解 宏任务&#xff08;Macrotasks&…

Three.JS教程5 threejs中的材质

Three.JS教程5 threejs中的材质 一、什么是Three.js材质&#xff1f;二、Three.js的材质类型1. 材质类型2. 材质的共用属性&#xff08;1&#xff09;.alphaHash : Boolean&#xff08;2&#xff09;.alphaTest : Float&#xff08;3&#xff09;.alphaToCoverage : Boolean&am…

白酒:制曲工艺的微生物多样性及其作用

在云仓酒庄豪迈白酒的制曲工艺中&#xff0c;微生物多样性是一个关键要素。曲是白酒生产中的重要配料&#xff0c;它由小麦、麸皮等原料制成&#xff0c;经过微生物的发酵和生长而形成。微生物的多样性和相互作用对曲的品质和白酒的口感具有重要影响。 首先&#xff0c;微生物多…

【后端高频面试题--设计模式上篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 往期精彩内容 【后端高频面试题–设计模式上篇】 【后端高频面试题–设计模式下篇】 【后端高频…

Git 操作以及Git 常见问题

Git 操作 git 教程&#xff1a;https://www.runoob.com/git/git-tutorial.html 基本概念 工作区&#xff1a;克隆项目到本地后&#xff0c;项目所在的文件夹&#xff1b; 暂存区&#xff1a;从工作区添加上来的变更&#xff08;新增&#xff0c;修改&#xff0c;删除&#xff…

C++面向对象程序设计-北京大学-郭炜【课程笔记(三)】

C面向对象程序设计-北京大学-郭炜【课程笔记&#xff08;三&#xff09;】 1、构造函数&#xff08;constructor&#xff09;1.1、基本概念 2、赋值构造函数2.1、基本概念2.1、复制构造函数起作用的三种情况2.2、常引用参数的使用 3、类型转换构造函数3.1、什么事类型转换构造函…

关于怎么监督机器学习训练的进度

不知道大家有没有我这种烦恼&#xff0c;运行机器学习模型的时候&#xff0c;一直在哪运行&#xff0c;也不知道啥时候会结束&#xff0c;等也不是&#xff0c;不等也不是&#xff0c;又着急想看到结果。 如下提出三种监督训练进度的方法&#xff1a; 1.使用回调函数&#xf…