【Nachos】山东大学操作系统实验五 具有二级索引的文件系统

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

文章目录

      • 一、完成情况概览
      • 二、思路分析
        • 1、原Nachos 文件头i-node结构和功能
        • 2、二级索引文件头i-node设计和功能维护
        • 1、Allocate(BitMap *freeMap, int fileSize)维护
        • 2、Deallocate(BitMap *freeMap)维护
        • 3、ByteToSector(int offset)维护
        • 4、Print()维护
        • 5、实验四的,ExtendFile(OpenFile *bitmapfile,int newSize)维护
        • 6、实验四的拓展功能、CutFile(OpenFile *bitmapfile,int newSize)维护
      • 四、debug记录
      • 五、结果展示
      • 四、debug记录
      • 五、结果展示

一、完成情况概览

  • 熟悉了解了Nachos的文件系统机制
  • 实现了二级索引文件头i-node设计和相关功能维护
  • 将实验二的文件扩展和cut升级成适配二级索引的版本

二、思路分析

1、原Nachos 文件头i-node结构和功能

  • 单层索引的结构

    dataSector数组有NumDirect项(按一个i-node占用空间不超过一个扇区的原则,计算可得NumDirect为30),每一项都是直接的单层索引,指向文件所占扇区。由此可得,文件最大大小是,30*128 bytes=3840bytes

      private:
        int numBytes;			// Number of bytes in the file
        int numSectors;			// Number of data sectors in the file
        int dataSectors[NumDirect];		// Disk sector numbers for each data 
    					// block in the file
    
  • 功能

    public:
        bool Allocate(BitMap *bitMap, int fileSize);// Initialize a file header, 
    						//  including allocating space 
    						//  on disk for the file data
        void Deallocate(BitMap *bitMap);  		// De-allocate this file's 
    						//  data blocks
        void FetchFrom(int sectorNumber); 	// Initialize file header from disk
        void WriteBack(int sectorNumber); 	// Write modifications to file header
    					//  back to disk
        int ByteToSector(int offset);	// Convert a byte offset into the file
    					// to the disk sector containing
    					// the byte
        int FileLength();			// Return the length of the file 
    					// in bytes
        void Print();			// Print the contents of the file.	
    //***********************************newSize(bytes) 
        bool ExtendFile(OpenFile *bitmapfile,int newSize);
        bool CutFile(OpenFile *bitmapfile,int newSize);
    
    

2、二级索引文件头i-node设计和功能维护

【Nachos】山东大学操作系统实验五 具有二级索引的文件系统_第1张图片

如图所示,我构建具有二级索引的i-node,思想就是这样,原先的前NumDirect-1项还是直接索引,最后一项,可以指向另一个块,这个块存放新的直接索引条目,因此产生二级索引,扩大了文件的最大size=(29+32)*128 bytes

二级的索引块是动态产生的,当文件大小不需要它时,最后一项设置为-1;当文件大小一级索引无法支持,再分配一个新的块存索引,将其地址存入最后一项,形成图上结构。

FileHeader类的私有成员和接口定义无需更改;但是除了FetchFrom,WriteBack,FileLength外的函数实现都要更改,以支持二级索引。三、实现步骤

1、Allocate(BitMap *freeMap, int fileSize)维护

bool
FileHeader::Allocate(BitMap *freeMap, int fileSize)
{ 
    numBytes = fileSize;
    numSectors  = divRoundUp(fileSize, SectorSize);
    if (numSectors >MaxNumSector || freeMap->NumClear() < numSectors)
	return FALSE;		// 超出文件最大size||not enough space

	if (numSectorsFind();
		dataSectors[NumDirect-1] = -1;   //无二级索引,最后一项是-1
	}else{ //使用二级索引
		printf("!!!Allocate使用二级索引!!!");	
		for (int i = 0; i < NumDirect; i++)
			dataSectors[i] = freeMap->Find(); //最后一项是二级块的地址
		int dataSectors2[NumIndirect];
		for (int i=0; i < numSectors-NumDirect+1; i++)
			dataSectors2[i] = freeMap->Find();
		//将二级索引保存
		synchDisk->WriteSector(dataSectors[NumDirect-1], (char *)dataSectors2); 
		
	}	
    return TRUE;
}

2、Deallocate(BitMap *freeMap)维护

void 
FileHeader::Deallocate(BitMap *freeMap)
{
	if (numSectorsTest((int) dataSectors[i]));  // ought to be marked!
		freeMap->Clear((int) dataSectors[i]);
		}
	else{
		printf("!!!Deallocate使用二级索引!!!");
		int dataSectors2[NumIndirect];
		synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
		
		for (int i = 0; i < NumDirect; i++){
		ASSERT(freeMap->Test((int) dataSectors[i]));  // ought to be marked!
		freeMap->Clear((int) dataSectors[i]);
		}
		for (int i=0; i < numSectors-NumDirect+1; i++){
		ASSERT(freeMap->Test((int) dataSectors2[i]));  // ought to be marked!
		freeMap->Clear((int) dataSectors2[i]);
		}
	}
}

3、ByteToSector(int offset)维护

int
FileHeader::ByteToSector(int offset)
{
	int sectorTh= offset / SectorSize;
	if (sectorTh < NumDirect-1)
		return(dataSectors[sectorTh]);
	else{
		int dataSectors2[NumIndirect];
		synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
		printf("########Kuai hao: %d\n",dataSectors2[sectorTh-NumDirect+1]);
		return(dataSectors2[sectorTh-NumDirect+1]);
	}	 
}

4、Print()维护

void
FileHeader::Print()
{
    int i, j, k;
    char *data = new char[SectorSize];
	
	if(numSectorsReadSector(dataSectors[i], data);
        for (j = 0; (j < SectorSize) && (k < numBytes); j++, k++) {
	    if ('\040' <= data[j] && data[j] <= '\176')   // isprint(data[j])
		printf("%c", data[j]);
            else
		printf("\\%x", (unsigned char)data[j]);
	}
        printf("\n"); 
    }
	}else{
		printf("!!!Print使用二级索引!!!");
		int dataSectors2 [NumIndirect];
		synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
		printf("FileHeader contents.  File size: %d.  File blocks:\n", numBytes);
		for (i = 0; i < NumDirect-1; i++)
			printf("%d ", dataSectors[i]);
		printf("\n二级索引块号%d ", dataSectors[NumDirect-1]);
		for (i = 0; i < numSectors-NumDirect+1; i++)
			printf("%d ", dataSectors2[i]);
		
	    for (i = k = 0; i < NumDirect-1; i++) {
			synchDisk->ReadSector(dataSectors[i], data);
			for (j = 0; (j < SectorSize) && (k < numBytes); j++, k++) {
				if ('\040' <= data[j] && data[j] <= '\176')   // isprint(data[j])
				printf("%c", data[j]);
				else
				printf("\\%x", (unsigned char)data[j]);
			}
			printf("\n"); 
		}	
		
	    for (i = 0; i < numSectors-NumDirect+1; i++) {
			synchDisk->ReadSector(dataSectors2[i], data);
			for (j = 0; (j < SectorSize) && (k < numBytes); j++, k++) {
				if ('\040' <= data[j] && data[j] <= '\176')   // isprint(data[j])
				printf("%c", data[j]);
				else
				printf("\\%x", (unsigned char)data[j]);
			}
			printf("\n"); 
		}
	}
    delete [] data;
}

5、实验四的,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",newNumSectors);
    if(newNumSectors>MaxNumSector||freeMap->NumClear()< diffSector){
	printf("扩展文件失败\n");
	return false;   //磁盘空间不足
    }
    //allocate the new sectors and store them into file header
	int i;
	
	if (newNumSectorsFind();
			//printf("debug in fhdr extend #########NEW KUAI HAO=%d \n",dataSectors[i]);
		}
	}else{
		printf("!!!ExtendFile使用二级索引!!!");
		if(numSectorsFind();
		}
		int dataSectors2 [NumIndirect];
		for (i=0; i < newNumSectors-NumDirect+1; i++)
			dataSectors2 [i] = freeMap->Find();
		//将二级索引保存
		synchDisk->WriteSector(dataSectors[NumDirect-1], (char *)dataSectors2); 
		}else{//原来有二级索引
		int dataSectors2 [NumIndirect];
		synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
		for (i=numSectors-NumDirect+1; i < newNumSectors-NumDirect+1; i++)
			dataSectors2[i] = freeMap->Find();
		//将二级索引保存
		synchDisk->WriteSector(dataSectors[NumDirect-1], (char *)dataSectors2);
			
		}
	}
    numBytes = newSize;
    numSectors = newNumSectors;
    
    freeMap->WriteBack(bitmapfile);
    printf("扩展文件成功\n");
    return true;
}

6、实验四的拓展功能、CutFile(OpenFile *bitmapfile,int newSize)维护

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;
	if(numSectorsClear(dataSectors[i]);
		}
	else{
		printf("!!!CutFile使用二级索引!!!");
		int dataSectors2[NumIndirect];
		synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
		
		if(newNumSectorsClear(dataSectors2[i]);
			for (i = newNumSectors; iClear(dataSectors[i]);
			dataSectors[NumDirect-1]= -1; //二级索引去掉
		}else{
			for(int i=newNumSectors-NumDirect+1; i < numSectors-NumDirect+1; i++)
				freeMap->Clear(dataSectors[i]);
					//将二级索引保存
			synchDisk->WriteSector(dataSectors[NumDirect-1], (char *)dataSectors2); 
		}
	}
    numBytes = newSize;
    numSectors = newNumSectors;

    freeMap->WriteBack(bitmapfile);
    printf("cut文件成功\n");
    return true;
}

四、debug记录

  • 二级索引记住保存
  • 文件扩展完,bitmap记住保存

五、结果展示

四、debug记录

  • 二级索引记住保存
  • 文件扩展完,bitmap记住保存

五、结果展示

【Nachos】山东大学操作系统实验五 具有二级索引的文件系统_第2张图片【Nachos】山东大学操作系统实验五 具有二级索引的文件系统_第3张图片【Nachos】山东大学操作系统实验五 具有二级索引的文件系统_第4张图片【Nachos】山东大学操作系统实验五 具有二级索引的文件系统_第5张图片【Nachos】山东大学操作系统实验五 具有二级索引的文件系统_第6张图片【Nachos】山东大学操作系统实验五 具有二级索引的文件系统_第7张图片【Nachos】山东大学操作系统实验五 具有二级索引的文件系统_第8张图片

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