6.1810: Operating System Engineering 2023 <Lab8 fs: File system>

2024-01-22 18:28

本文主要是介绍6.1810: Operating System Engineering 2023 <Lab8 fs: File system>,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、本节任务

二、Lab8: file system

在这一节,我们将为 xv6 的文件系统加入大文件和符号链接。

2.1 Large files (moderate) 

这个部分需要我们增加 xv6 文件的大小上限,由于 inode 结构体中有 12 个直接映射项,1 个一级间接映射项,所以 xv6 文件系统中的最大文件大小为 (12 + (1024B / 4B)) 个块,即 268 个块,在 xv6 中,每个块大小为 1024B。而通过再增加一个二级间接映射项可以让我们的文件大小增加到 (11 + 256 + 256*256) = 65803 个块,而下面我们就是要实现这个二级间接映射项。

首先修改 fs.h 文件中的宏和 dinode 中 addrs 的大小,以及 file.h 文件中 inode 结构体中 addrs 的大小也要同步修改过来。这样做的目的是减少一个直接映射项,增加一个二级间接映射项。

#define NDIRECT 11
#define NINDIRECT (BSIZE / sizeof(uint))
#define MAXFILE (NDIRECT + NINDIRECT + NINDIRECT * NINDIRECT)// 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
};
// in-memory copy of an inode
struct inode {uint dev;           // Device numberuint inum;          // Inode numberint ref;            // Reference countstruct sleeplock lock; // protects everything below hereint valid;          // inode has been read from disk?short type;         // copy of disk inodeshort major;short minor;short nlink;uint size;uint addrs[NDIRECT+2];
};

然后再修改 fs.c 文件中的 bmap 和 itrunc 函数,bmap 函数的作用是通过逻辑块号 bn 来到 addrs 数组中找到其在磁盘上的真实块号;而 itrunc 函数的作用是将 inode 的 addrs 清空。直接映射项的真实块号就是 addrs[bn],而一级间接映射项的真实块号还需要从 addrs[NDIRECT] 指向的块上寻找真实块号,二级间接映射项需要从 addrs[NDIRECT+1] 指向的块上先找到对应一级间接映射项,然后再找到真实块号。

static uint
bmap(struct inode *ip, uint bn)
{uint addr, *a;struct buf *bp;if(bn < NDIRECT){if((addr = ip->addrs[bn]) == 0){addr = balloc(ip->dev);if(addr == 0)return 0;ip->addrs[bn] = addr;}return addr;}bn -= NDIRECT;if(bn < NINDIRECT){// Load indirect block, allocating if necessary.if((addr = ip->addrs[NDIRECT]) == 0){addr = balloc(ip->dev);if(addr == 0)return 0;ip->addrs[NDIRECT] = addr;}bp = bread(ip->dev, addr);a = (uint*)bp->data;if((addr = a[bn]) == 0){addr = balloc(ip->dev);if(addr){a[bn] = addr;log_write(bp);}}brelse(bp);return addr;}bn -= NINDIRECT;if(bn < NINDIRECT * NINDIRECT){if((addr = ip->addrs[NDIRECT+1]) == 0){addr = balloc(ip->dev);if(addr == 0)return 0;ip->addrs[NDIRECT+1] = addr;}bp = bread(ip->dev, addr);a = (uint*)bp->data;if((addr = a[bn/NINDIRECT]) == 0){addr = balloc(ip->dev);if(addr == 0)return 0;a[bn/NINDIRECT] = addr;log_write(bp);}brelse(bp);bn = bn % NINDIRECT;bp = bread(ip->dev, addr);a = (uint*)bp->data;if((addr = a[bn]) == 0){addr = balloc(ip->dev);if(addr){a[bn] = addr;log_write(bp);}}brelse(bp);return addr;}panic("bmap: out of range");
}
void
itrunc(struct inode *ip)
{int i, j;struct buf *bp;struct buf *bp1;uint *a;uint *a1;for(i = 0; i < NDIRECT; i++){if(ip->addrs[i]){bfree(ip->dev, ip->addrs[i]);ip->addrs[i] = 0;}}if(ip->addrs[NDIRECT]){bp = bread(ip->dev, ip->addrs[NDIRECT]);a = (uint*)bp->data;for(j = 0; j < NINDIRECT; j++){if(a[j])bfree(ip->dev, a[j]);}brelse(bp);bfree(ip->dev, ip->addrs[NDIRECT]);ip->addrs[NDIRECT] = 0;}if(ip->addrs[NDIRECT+1]){bp = bread(ip->dev, ip->addrs[NDIRECT+1]);a = (uint*)bp->data;for(i = 0; i < NINDIRECT; i++){if(a[i]){bp1 = bread(ip->dev, a[i]);a1 = (uint*)bp1->data;for(j = 0; j < NINDIRECT; j++){if(a1[j])bfree(ip->dev, a1[j]);}brelse(bp1);bfree(ip->dev, a[i]);a[i] = 0;}}brelse(bp);bfree(ip->dev, ip->addrs[NDIRECT+1]);ip->addrs[NDIRECT+1] = 0;}ip->size = 0;iupdate(ip);
}

最后通过测试。

2.2 Symbolic links (moderate)

首先创建一个新系统调用 symlink,怎么添加系统调用在之前的 lab 中已经做过了,这里就不多赘述了。

下面是 symlink 系统调用的实现,首先使用 create 创建一个新文件,文件的类型为 T_SYMLINK,然后使用 writei 向文件的数据块写入 target 路径,这样使用 open 系统调用时如果发现文件是链接文件,则从文件的数据块中读取 target 文件的路径。最后记得使用 iunlockput(ip) 释放 inode 的锁和引用:

uint64 sys_symlink(void)
{int n;char target[MAXPATH];char path[MAXPATH];struct inode *ip;if((n = argstr(0, target, MAXPATH)) < 0 || argstr(1, path, MAXPATH) < 0){return -1;}begin_op();ip = create(path, T_SYMLINK, 0, 0);if(ip == 0){end_op();return -1;}if(writei(ip, 0, (uint64)target, 0, MAXPATH) != MAXPATH){iunlockput(ip);end_op();return -1;}iunlockput(ip);end_op();return 0;
}

然后需要修改 open 系统调用,当识别到文件的类型为 T_SYMLINK 的时候,并且模式不为 O_NOFOLLOW,则循环地通过链接路径找到被链接的文件,若被链接的文件就是当前文件本身,形成的环路,或者链接的深度超过了 10,则报错:

uint64
sys_open(void)
{char path[MAXPATH];char target[MAXPATH];int fd, omode;struct file *f;struct inode *ip;struct inode *tip;int n, depth;argint(1, &omode);if((n = argstr(0, path, MAXPATH)) < 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;}}depth = 0;while(ip->type == T_SYMLINK && !(omode & O_NOFOLLOW)){if(readi(ip, 0, (uint64)target, 0, MAXPATH) != MAXPATH)panic("open symlink: readi");// the links form a cycleif(strncmp(target, path, n) == 0){iunlockput(ip);end_op();return -1;}// target file does not existif((tip = namei(target)) == 0){iunlockput(ip);end_op();return -1;}iunlock(ip);ilock(tip);ip = tip;depth++;if(depth >= 10){iunlockput(ip);end_op();return -1;}}
.....
.....

最后通过所有测试。 

这篇关于6.1810: Operating System Engineering 2023 <Lab8 fs: File system>的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/633847

相关文章

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

Partical System

创建"粒子系统物体"(点击菜单GameObject -> Create Other -> Particle System) 添加"粒子系统组件"(点击Component -> Effects  ->Particle System) 粒子系统检视面板  点击粒子系统检视面板的右上角的"+"来增加新的模块。(Show All Modules:显示全部) 初始化模块: •

小技巧绕过Sina Visitor System(新浪访客系统)

0x00 前言 一直以来,爬虫与反爬虫技术都时刻进行着博弈,而新浪微博作为一个数据大户更是在反爬虫上不遗余力。常规手段如验证码、封IP等等相信很多人都见识过…… 当然确实有需要的话可以通过新浪开放平台提供的API进行数据采集,但是普通开发者的权限比较低,限制也比较多。所以如果只是做一些简单的功能还是爬虫比较方便~ 应该是今年的早些时候,新浪引入了一个Sina Visitor Syst

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多

Open a folder or workspace... (File -> Open Folder)

问题:vscode Open with Live Server 时 显示Open a folder or workspace... (File -> Open Folder)报错 解决:不可以单独打开文件1.html ; 需要在文件夹里打开 像这样

android java.io.IOException: open failed: ENOENT (No such file or directory)-api23+权限受权

问题描述 在安卓上,清单明明已经受权了读写文件权限,但偏偏就是创建不了目录和文件 调用mkdirs()总是返回false. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.READ_E

System.getProperties().

Java.version Java 运行时环境版本 java.vendor Java 运行时环境供应商 java.vendor.url Java 供应商的 URL java.home Java 安装目录 java.vm.specification.version Java 虚拟机规范版本 java.vm.specification.vendor

12C 新特性,MOVE DATAFILE 在线移动 包括system, 附带改名 NID ,cdb_data_files视图坏了

ALTER DATABASE MOVE DATAFILE  可以改名 可以move file,全部一个命令。 resue 可以重用,keep好像不生效!!! system照移动不误-------- SQL> select file_name, status, online_status from dba_data_files where tablespace_name='SYSTEM'

bash: arm-linux-gcc: No such file or directory

ubuntu出故障重装了系统,一直用着的gcc使用不了,提示bash: arm-linux-gcc: No such file or directorywhich找到的命令所在的目录 在google上翻了一阵发现此类问题的帖子不多,后来在Freescale的的LTIB环境配置文档中发现有这么一段:     # Packages required for 64-bit Ubuntu

编译linux内核出现 arm-eabi-gcc: error: : No such file or directory

external/e2fsprogs/lib/ext2fs/tdb.c:673:29: warning: comparison between : In function 'max2165_set_params': -。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。 。。。。。。。。 host asm: libdvm <= dalvik/vm/mterp/out/Inte