MIT 6s081 lab9:file system

2024-01-16 00:12
文章标签 system file mit 6s081 lab9

本文主要是介绍MIT 6s081 lab9:file system,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Lab9: file system

作业地址:Lab: file system (mit.edu)

文件系统的实验,需要对提前阅读fs.c\bio.c\sysfile.c以及相关头文件

Large files (moderate)

本实验为xv6的文件系统添加大文件支持

原本的xv6文件系统的每个inode结构体,采用混合索引的方式记录数据所在的盘块号,如下图。

在这里插入图片描述

对于文件的前12KB数据,可以通过直接访问inode得到盘块号(每个盘块1024字节),address1~12,对于大于12个盘块的文件,会分配一个一级索引表(一个盘块,1024KB大小,用于存储这部分数据的所在盘块号。),一个一级索引表可以包含BSIZE/4 = 256个盘块号,加上直接索引的12个盘块号, 总共是268个盘块。也就是说一个文件最多268KB。

本实验实现系统的大文件,减少一个直接索引的盘块,改成二级索引表(占一个盘块,可以包含256个一级索引表,每个一级索引表又包含256个盘块号,也就是最大的文件大小变为11+256+256*256)个块,也就是65803KB。

跟前面的页表有点像

1、修改NDIRECT和MAXFILE,修改dinode和inode结构体addrs数组长度

// fs.h
#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
};
//file.h
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];
};

2、修改bmap,使其能够识别二级索引,当查出一级块号后,需将一级块的数据读入,再次查询

static uint
bmap(struct inode *ip, uint bn)
{uint addr, *a;struct buf *bp;// printf("bn = %d\n", bn);if(bn < NDIRECT){ // NDIRECTif((addr = ip->addrs[bn]) == 0)ip->addrs[bn] = addr = balloc(ip->dev);return addr;}bn -= NDIRECT;// printf("bn = %d, NINDIRECT = %d\n", bn + NDIRECT, NINDIRECT); // 256if(bn < NINDIRECT) { // 第一级可以直接搞定// Load indirect block, allocating if necessary.if((addr = ip->addrs[NDIRECT]) == 0){// printf("here1\n");ip->addrs[NDIRECT] = addr = balloc(ip->dev); //申请一个block for indirect block}bp = bread(ip->dev, addr); // 从磁盘中读取数据到block中,addr是indirect的地址a = (uint*)bp->data; // buf中的数据头,也就是说a里面有256项if((addr = a[bn]) == 0){a[bn] = addr = balloc(ip->dev);log_write(bp);}brelse(bp);return addr;}else{bn -= NINDIRECT;// printf("%d\n", bn);if(bn < NINDIRECT * NINDIRECT) {// printf("bn=%d\n",bn+ NDIRECT - 1+NINDIRECT);if((addr = ip->addrs[NDIRECT + 1]) == 0) {ip->addrs[NDIRECT + 1] = addr = balloc(ip->dev); // 申请一个block for double-indirect block// printf("here2:addr = %d\n", addr);}int i = bn / NINDIRECT, j = bn % NINDIRECT;bp = bread(ip->dev, addr);a = (uint*)bp->data; // 此时a中存放的是二级块的地址if((addr = a[i]) == 0) // 如果此时一级块指向的block地址为空,则 {a[i] = addr = balloc(ip->dev); // 再申请一个blocklog_write(bp);} brelse(bp); // 及时释放struct buf *bp_double = bread(ip->dev, addr); // 再次查询!a = (uint*)bp_double->data; // 再次查询!if((addr = a[j]) == 0) {a[j] = addr = balloc(ip->dev);log_write(bp_double);}brelse(bp_double);// printf("%p\n", addr);return addr;}}panic("bmap: out of range");
}

3、修改itrunc,释放所有的块,包括直接、一级、二级索引的表

void
itrunc(struct inode *ip)
{int i, j;struct buf *bp;uint *a;for(i = 0; i < NDIRECT; i++){ // NDIRECTif(ip->addrs[i]){bfree(ip->dev, ip->addrs[i]);ip->addrs[i] = 0;}}if(ip->addrs[NDIRECT]){  // NDIRECTbp = bread(ip->dev, ip->addrs[NDIRECT - 1]); // NDIRECTa = (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]); // NDIRECTip->addrs[NDIRECT] = 0; // NDIRECT}if(ip->addrs[NDIRECT + 1]) {bp = bread(ip->dev, ip->addrs[NDIRECT + 1]); a = (uint*)bp->data;for(j = 0; j < NINDIRECT; j++){if(a[j]){struct buf *bp_double = bread(ip->dev, a[j]);uint* a_double = (uint*)bp_double->data;for(int k = 0; k < NINDIRECT; k++){if(a_double[k]) {bfree(ip->dev, a_double[k]);a_double[k] = 0;}  }brelse(bp_double);bfree(ip->dev, a[j]);a[j] = 0;}}brelse(bp);bfree(ip->dev, ip->addrs[NDIRECT + 1]); // NDIRECTip->addrs[NDIRECT + 1] = 0; // NDIRECT}ip->size = 0;iupdate(ip);
}

测试通过

$ bigfile
...
wrote 65803 blocks
bigfile done; ok
$ usertests
usertests starting
test manywrites: OK
test execout: OK
...
test forktest: OK
test bigdir: OK
ALL TESTS PASSED

Symbolic links (moderate)

使用symlink系统调用(和lab1一样的流程创建系统调用),创建符号链接,符号链接和其他文件一样,使用inode块,使用第一个块存储符号链接指向的文件

uint64 sys_symlink(void) //symlink(char *target, char *path) 
{char target[MAXPATH], path[MAXPATH];if(argstr(0, target, MAXPATH) < 0 || argstr(1, path, MAXPATH) < 0)return -1;// printf("target = %s, path = %s\n", target, path);// 创建软连接 path -> target// 不需要判断 target是否存在struct inode* ip;begin_op();ip = create(path, T_SYMLINK, 0, 0);if(ip == 0){end_op();return -1;}if(writei(ip, 0, (uint64)target, 0, strlen(target)) < 0){ //写入targetend_op();return -1;}iunlockput(ip);end_op();return 0;
}

在fcntl.h中补齐O_NOFOLLOW的定义

#define O_RDONLY   0x000
#define O_WRONLY   0x001
#define O_RDWR     0x002
#define O_CREATE   0x200
#define O_TRUNC    0x400
#define O_NOFOLLOW 0x800

修改sys_open函数,使其在遇到符号链接,并且没有O_NOFOLLOW标志时,递归地寻找直到非符号链接的inode

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 { // add beginif((ip = namei(path)) == 0){end_op();return -1;}ilock(ip);if(ip->type == T_SYMLINK && !(omode & O_NOFOLLOW)) { // 如果是符号链接并且没有不跟随标志int max_depth = 10; // 定义最大递归深度char target[MAXPATH];int found = 0;for(int i = 0; i < max_depth; i++) {if(readi(ip, 0, (uint64)target, 0, MAXPATH) < 0) {iunlockput(ip);end_op();return -1;}iunlockput(ip);ip = namei(target);if(ip == 0) break;if(ip->type == T_SYMLINK) ilock(ip);else{found = 1;ilock(ip);break;}}if(!found){end_op();return -1;}}// add endif(ip->type == T_DIR && omode != O_RDONLY){iunlockput(ip);end_op();return -1;}}...
}

测试:

$ symlinktest
Start: test symlinks
test symlinks: ok
Start: test concurrent symlinks
test concurrent symlinks: ok
$ usertests
usertests starting
test manywrites: OK
test execout: OK
test copyin: OK
test copyout: OK
...
test iref: OK
test forktest: OK
test bigdir: OK
ALL TESTS PASSED

这篇关于MIT 6s081 lab9:file system的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Partical System

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

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

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

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

file-max与ulimit的关系与差别

http://zhangxugg-163-com.iteye.com/blog/1108402 http://ilikedo.iteye.com/blog/1554822

瑞芯微Parameter File Format解析

Rockchip android系统平台使用parameter文件来配置一些系统参数 主要包含:串口号:nandflash分区 固件版本,按键信息等; 如下是台电P98HD的parameter参数: FIRMWARE_VER:4.1.1        // 固件版本 //固件版本,打包 updata.img 时会使用到,升级工具会根据这个识别固件版本。 //Boot loader 会读取