nachos 实验5
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Lab5 Extendable Files
实验目标
Nachos的文件系统是一个简单并且能力有限的系统,限制之一就是文件的大小是不可扩展的:一旦我们在创建一个文件时规定了它的大小,文件的大小就不能再改变。本次实验的目的即是设计扩展Nachos的文件系统,使得文件的大小是可以被扩展的。完成以下要求:
当一个文件被创建的时候,它的初始大小可以为0。
如果更多的数据被写入到一个文件中,它的大小可以随之增加。
实验环境
ubuntu操作系统nachos-3.4 gcc-2.8.1-mips编译器
关键源代码及注释
Nachos的文件系统主要包含Disk, SynchDisk, BitMap, FileHeader, OpenFile, Directory, FileSystem这几个类。其中,Disk, SynchDisk, BitMap, Directory, FileSystem是文件系统的底层类,里面描述了Nachos的文件系统的基本文件信息以及和磁盘操作的结合。FileSystem中描述的是文件的创建、打开、删除等操作。FileHeader定义操作是文件头的初始化、为数据在磁盘上分配空间、磁盘上文件的读取和写回。OpenFile 中主要涉及文件的读、写、读写指针的重定位等操作。
根据中的create函数,可以看到,在创建文件时,需要给定该文件初始大小。再看openfile里的ReadAt和WriteAt函数,如果要读出或者要写入的字节数太多,文件系统就会自动将多出来的部分舍弃掉。
if ((position + numBytes) > fileLength)
numBytes = fileLength - position;
如果文件的大小(fileLength)一直不变,那么必然无法实现文件的扩展。
Directory为文件的索引,存放DirectoryEntry,DirectoryEntry给出了文件的名字,以及在磁盘上的位置,Fig.1为未进行任何操作时Directory中各个DirectoryEntry存放的内容。
Fig. 1 Directory 的各个entry内容示意图
再看FileSystem的各个函数。
create:
当一个文件被创建时,Directory会根据1号DirectoryEntry里的内容(0号为BitMap 的索引),找到空闲的扇区,然后为文件头分配扇区,接下来,在磁盘上为分配空间,最后将索引,BitMap,以及磁盘更新。
Open:
当打开一个文件时,Directory会根据文件名找到该文件的文件头所在的扇区,然后返回一个openfile。
所以,如果要扩展文件系统,可以先改变文件的大小(原文件大小+追加文件的大小),算出需要多分配的磁盘,然后找到该文件的文件头所在的扇区,为该文件重新分配空间,将追加的内容写入磁盘,最后更新文件头和索引块中的信息。
在fileheader里增加AppendSector方法:
//根据要追加的文件的大小来分配要追加的sector
bool
FileHeader::AppendSector(BitMap *bitMap, int fileSize)
{
int totalLength=numSectors*SectorSize;
int restLength=totalLength-numBytes;
if(restLength int appendLength=fileSize-restLength; int appendSectors = divRoundUp(appendLength, SectorSize); if (bitMap->NumClear() < appendSectors) return FALSE; // not enough space numBytes=numBytes+fileSize; numSectors=numSectors+appendSectors; for(int i=numSectors-appendSectors;i dataSectors[i] = bitMap -> Find(); return true; } else{//最后一个扇区未写满且要追加的大小小于余下的扇区 numBytes=numBytes+fileSize; return true; } } 在openfile里增加AppendSize和WriteBack方法 //给追加的文件分配扇区 bool OpenFile:: AppendSize(int numBytes) { //计算需要多少扇区 /*int firstSector, lastSector, numSectors; firstSector = divRoundDown(seekPosition, SectorSize); lastSector = divRoundDown(seekPosition + numBytes - 1, SectorSize); numSectors = 1 + lastSector - firstSector;*/ OpenFile *newFile= new OpenFile(0);//第0块指向存放bitmap的sector BitMap *freeMap = new BitMap(NumSectors); freeMap->FetchFrom(newFile); if(!(hdr->AppendSector(freeMap, numBytes))) return false; freeMap->WriteBack(newFile); delete newFile; delete freeMap; return true; } WriteBack方法: void OpenFile::WriteBack(char *name) { OpenFile *file = new OpenFile(1);//第一块指向存放filehdr索引的sector Directory *directory = new Directory(10);//directory里共有10块sector directory->FetchFrom(file); //把文件的内容重新写入sector int sector = directory ->Find(name); hdr->WriteBack(sector); delete file; delete directory; } 修改fstest里的Append方法: 修改部分: ASSERT(openFile != NULL);