【Nachos】山东大学操作系统实验四 扩展文件系统

完整源码见本人博客下载资源

文章目录

      • 一、完成情况概览
      • 二、Nachos文件系统机制研究
        • 1、 **Nachos** 文件系统的组织结构
        • 2、例子:Nachos如何创建文件,读写文件
          • 1)创建文件
          • 2)读写文件
        • 3、Nachos的文件为什么是不可扩展的
      • 三、实现扩展文件
        • 1、给OpenFile增加ChangeFileSize(int newSize)接口
        • 2、给FileHeader增加ExtendFile(OpenFile *bitmapfile,int newSize)接口
        • 3、更改OpenFile的write函数
        • 4、在OpenFile增加inode的writeback函数,更新inode磁盘内容
        • 5、测试展示
      • 四、实现cut文件和其测试函数
        • 1、在FileHeader增加CutFile(OpenFile *bitmapfile,int newSize)接口
        • 2、扩充Nachos命令行参数 -hap2
        • 3、测试展示

一、完成情况概览

  • 熟悉了解了Nachos的文件系统机制
  • 实现了文件扩展
  • 实现了文件cut,并编写新的命令行参数 -hap2的对应函数进行测试
  • 特点,遵循Nachos文件系统组织结构,在合适的地方增改

二、Nachos文件系统机制研究

1、 Nachos 文件系统的组织结构

  • 磁盘其实就是,unix下的一个名字叫Disk的文件

  • 其中I/O控制层,DISK模块完成的工作实际上是将文件指针定位到合适位置,读写Disk的文件。

  • 基本文件层SynchDisk,给‘磁盘’读写加锁,保证同步

【Nachos】山东大学操作系统实验四 扩展文件系统_第1张图片

2、例子:Nachos如何创建文件,读写文件

1)创建文件
  • 文件系统最高层——Filesys调用它的成员函数Create(char *name, int initialSize)
  • 然后访问Directory,判断是否还有空目录项
  • 访问Bitmap,查看是否有空扇区,来放置header
  • 如果有空间,增加新目录项,创建新的FileHeader,在hdr中给文件分配空间,再次访问Bitmap,检查是否还有空扇区
  • 如果空间足够,文件allocate成功,将header写回磁盘(位置是第三步分配的扇区),将目录写回磁盘
2)读写文件
  • 文件系统最高层——Filesys调用它的成员函数Open(char *name)
  • 然后访问Directory,根据文件名Find到该文件i-node扇区位置
  • OpenFile利用i-node位置,完成文件打开操作
  • 在OpenFile里调用 Write(char *from, int numBytes),开始写文件
  • 写的时候,会访问header,查看FileSize等属性
  • 写文件调用SynchDisk,SynchDisk再调用Disk

3、Nachos的文件为什么是不可扩展的

由前两步,对文件创建,读写的操作流程,可以看出。

  • 一个文件的大小是在创建时定的,在header,allocate时候,传入参数fileSize,按fileSize分配恰好合适大小的扇区数量
  • 在openfile的write时,当写的位置超过fileSize时,会直接切掉超出部分,只是write不超出部分
  • 所以一个文件的大小从创建开始是不会改变的

三、实现扩展文件

根据上面的分析可以知道,实现后期改变文件大小,主要需要修改,OpenFile和FileHeader

1、给OpenFile增加ChangeFileSize(int newSize)接口

  • 遵循Nachos文件系统组织结构,FileHeader不访问OpenFile,所以在该接口中将调用FileHeader的成员函数,实现文件扩展,并将bitmap的OpenFile对象作为参数传入
  • 方便增加测试函数,扩充Nachos命令行参数
bool
OpenFile::ChangeFileSize(int newSize)
{
    int file_size=hdr->FileLength();
    OpenFile *bitmapfile = new OpenFile(0);

    if(newSize==file_size)
    {
	printf("改变文件大小成功!");
	return true;
    }
    if(newSize>file_size)
	return hdr->ExtendFile(bitmapfile,newSize);
    else if(newSize>0) 
	return hdr->CutFile(bitmapfile,newSize);
    else
	printf("cut文件失败!");
	return false;
}

2、给FileHeader增加ExtendFile(OpenFile *bitmapfile,int newSize)接口

如果空间足够,分配需要空间,修改相关成员变量

bool
FileHeader::ExtendFile(OpenFile *bitmapfile,int newSize)
{
    int newNumSectors  = divRoundUp(newSize, SectorSize);//上取整

    if(newNumSectors == numSectors){
        numBytes = newSize; 
	printf("扩展文件成功\n");
        return true;    //扇区数量不变
    }

    int diffSector = newNumSectors - numSectors;    

   // OpenFile *bitmapfile = new OpenFile(0);
    BitMap *freeMap = new BitMap(NumSectors);
    freeMap->FetchFrom(bitmapfile);

    //printf("debug in fhdr extend where new Sector=%d \n",freeMap->NumClear());
    if(newNumSectors>NumDirect||freeMap->NumClear()< diffSector){
	printf("扩展文件失败\n");
	return false;   //磁盘空间不足
    }
    //allocate the new sectors and store them into file header
    int i;
    for(i = numSectors; iFind();
    }
    numBytes = newSize;
    numSectors = newNumSectors;

    printf("扩展文件成功\n");
    return true;

}

3、更改OpenFile的write函数

write时空间不够,将触发文件扩展。

if ((numBytes <= 0) || (position > fileLength))
    	return 0; 				// check request
    if ((position + numBytes) > fileLength)
	if (!ChangeFileSize(position+numBytes))	
	    numBytes = fileLength - position;  //如果扩展失败还按照原方式将,多出来的字节去掉

4、在OpenFile增加inode的writeback函数,更新inode磁盘内容

void
OpenFile::WriteBack()
{
    hdr->WriteBack(hdrSector);
}

5、测试展示

【Nachos】山东大学操作系统实验四 扩展文件系统_第2张图片【Nachos】山东大学操作系统实验四 扩展文件系统_第3张图片
【Nachos】山东大学操作系统实验四 扩展文件系统_第4张图片
【Nachos】山东大学操作系统实验四 扩展文件系统_第5张图片
【Nachos】山东大学操作系统实验四 扩展文件系统_第6张图片【Nachos】山东大学操作系统实验四 扩展文件系统_第7张图片

四、实现cut文件和其测试函数

OpenFile的增改在上一步中已经完成

1、在FileHeader增加CutFile(OpenFile *bitmapfile,int newSize)接口

功能是,缩减文件,将多余部分cut掉

bool
FileHeader::CutFile(OpenFile *bitmapfile,int newSize)
{
    int newNumSectors  = divRoundUp(newSize, SectorSize);//上取整

    if(newNumSectors == numSectors){
        numBytes = newSize; 
	printf("cut文件成功\n");
        return true;    //扇区数量不变
    }
    

    //OpenFile *bitmapfile = new OpenFile(0);
    BitMap *freeMap = new BitMap(NumSectors);
    freeMap->FetchFrom(bitmapfile);
  //cut off 
    int i;
    for(i = newNumSectors; iClear(dataSectors[i]);
    }
    numBytes = newSize;
    numSectors = newNumSectors;

    printf("cut文件成功\n");
    return true;

}

2、扩充Nachos命令行参数 -hap2

它将调用HAppend(char *unixFile,char *nachosFile)接口

实现的功能同-hap,增加这个函数,是为了测试cutFile接口

void 
HAppend(char *unixFile,char *nachosFile)
{
//cut half of nachosfile

    OpenFile* openFile;
    if ( (openFile = fileSystem->Open(nachosFile)) == NULL)
    {
	// file "to" does not exits, then create one
	if (!fileSystem->Create(nachosFile, 0)) 
	{
	    printf("Append: couldn't create the file %s to append\n",nachosFile);
	    return;
	}
	openFile = fileSystem->Open(nachosFile);
    }

    ASSERT(openFile != NULL);
    int fileSize = openFile->Length();
    openFile->ChangeFileSize(fileSize/2);
    openFile->WriteBack();
    printf("inodes have been written back\n");
    
    // Close the UNIX and the Nachos files
    delete openFile;
    Append(unixFile,nachosFile,0); 
    
}

3、测试展示

【Nachos】山东大学操作系统实验四 扩展文件系统_第8张图片
可以看到,效果和-hap一样,说明,CutFile是成功的
【Nachos】山东大学操作系统实验四 扩展文件系统_第9张图片

你可能感兴趣的:(操作系统,操作系统,c++)