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

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

一、完成情况概览

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

二、Nachos文件系统机制研究

1、 Nachos 文件系统的组织结构
  • 磁盘其实就是,unix下的一个名字叫Disk的文件

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

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

在这里插入图片描述

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; i<newNumSectors; i++)
    {
        dataSectors[i] = freeMap->Find();
    }
    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、测试展示

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

四、实现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; i<numSectors; i++)
    {
        freeMap->Clear(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、测试展示

在这里插入图片描述
可以看到,效果和-hap一样,说明,CutFile是成功的
在这里插入图片描述

  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值