山东大学软件学院操作系统课程设计Nachos-实验五-具有二级索引的文件系统

说明:blog 中写到的这几个实验,不全面而且也不是上交实验报告的最终版本(是自己实验过程中用typora简单记录的笔记),完整内容(含代码+实验报告)可以通过(山东大学软件学院操作系统课设)下载,或者微信公众号关注“陌兮blog”免费获取
在这里插入图片描述

一、二级索引

1、问题分析

在 …/lab4 中,改进了 Nachos 文件系统的功能使它具有了扩展文件长度的功能,但文件扩展后文件的最大长度不能超出 3840 这个最大容量,也就是只能使用一级索引,所以本实验要实现的功能为nachos的二级索引。

在实验指导书中有关于nachos二级索引的相关讲解。在 Nachos 当前的设计中,文件数据空间的分配采用了一级索引方式。文件头(inode)仅能记录 NumDirect(这个值等于 30)个扇号。因此一个 Nachos 文件的最大容量仅有 NumDirect*SectorSize=3840 字节。现在我们的任务就是要在 Nachos 文件系统中增加类似 Unix 文件系统的多级索引方式,扩充 Nachos 能够记录的扇号,从而增大 Nachos 文件的最大容量。

查看源码文件 filehdr.h,可以看到定义了两个变量 NumDirect 和 MaxFileSize,分别表示nachos中,原有的一级索引能记录的扇区号数量与文件大小的最大值。
在这里插入图片描述

大概的思路是,首先定义dataSector2数组存储二级索引的扇区地址,一级索引数组的最后一项标记是否使用二级索引,以及存储二级索引数组的地址。如果未使用二级索引,则将一级索引数组中dataSector[numDirect]赋值为-1,如果使用二级索引,dataSector[numDirect]存储二级索引dataSector2所在的块号。当判断出文件大小超过一级索引的容量时,通过bitmap为文件头的dataSectors2分配空间,返回的Sector号存在一级索引数组的最后一项中。在读取文件数据时,同样先通过一级索引读取数据,然后通过一级索引最后一项获取二级索引的地址,然后访问二级索引读取文件数据。

需要修改 lab4 实现的ExtendSpace方法,使其可以扩展的空间更大,可处理二级索引;修改Allocate方法,使其在创建文件时可分配二级索引;修改Deallocate方法,使其在释放空间时,可对二级索引进行处理;修改ByteToSector方法,使其可以查询二级索引下的数据;最后再修改Print方法,增加二级索引相关内容的打印,便于调试输出,验证结果正确性。

2、实现二级索引

首先在filehdr.h文件中定义二级索引机制下,文件的最大扇区数和二级索引能够记录的扇号数量

#define MaxNumSector   ((SectorSize*2 - 3 * sizeof(int)) / sizeof(int))
#define NumDirect2  (SectorSize / sizeof(int)) //二级索引

修改filehdr.cc文件中ExtendSpace方法,增加二级索引的创建

//lab5 changed+++++++++++++++++++++++++++++++
bool
FileHeader::ExtendSpace(OpenFile *bitmapfile,int newSize)
{
    int newNumSectors  = divRoundUp(newSize, SectorSize);
    if(newNumSectors == numSectors){
        numBytes = newSize; 
        return true;
    }
	//需要扩展的扇区
    int diffSector = newNumSectors - numSectors;    
    BitMap *freeMap = new BitMap(NumSectors);
    freeMap->FetchFrom(bitmapfile);	
   //文件过大(超过二级索引)|| 磁盘空间不足
    if(newNumSectors>MaxNumSector||freeMap->NumClear()< diffSector){
		return false;
    }	
    //分配扇区,修改文件头信息
	int i;
	//不需要二级索引
	if (newNumSectors<NumDirect){ 
		for(i = numSectors; i<newNumSectors; i++)
		{
			dataSectors[i] = freeMap->Find();
		}
	//需要二级索引
	}else{	
		//二级索引
		int dataSectors2 [NumDirect2];
		//扩展前未使用二级索引
		if(numSectors<NumDirect){	
			for(i = numSectors; i<NumDirect; i++)
			{
				dataSectors[i] = freeMap->Find();
			}
			//二级索引部分
			for (i=0; i < newNumSectors-NumDirect+1; i++)
				dataSectors2[i] = freeMap->Find();
		}else{//扩展前已经使用二级索引
			//读取二级索引
			synchDisk->ReadSector(dataSectors[NumDirect-1], (char *)dataSectors2);
			for (i=numSectors-NumDirect+1; i < newNumSectors-NumDirect+1; i++)
				dataSectors2[i] = freeMap->Find();		
		}
		//二级索引地址保存在一级索引的最后一项dataSectors[NumDirect-1]
		synchDisk->WriteSector(dataSectors[NumDirect-1], (char *)dataSectors2);
	}
	//更新文件头信息
    numBytes = newSize;
    numSectors = newNumSectors;
    
    freeMap->WriteBack(bitmapfile);
    return true;
}
//lab5 changed+++++++++++++++++++++++++++++++

修改filehdr.cc文件中Allocate方法,增加可分配文件的大小,可创建二级索引

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cJbwzSUa-1642244354919)(实验报告.assets/image-20211211205635254.png)]

修改filehdr.cc文件中Deallocate方法,增加对二级索引空间的释放

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DtwM6W4R-1642244354919)(实验报告.assets/image-20211211205848322.png)]

修改filehdr.cc文件中ByteToSector方法,增加二级索引下扇区号的返回

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UvwBtqX2-1642244354920)(实验报告.assets/image-20211211205921917.png)]

修改filehdr.cc文件中Print方法,打印输出二级索引相关数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z4eXyVra-1642244354920)(实验报告.assets/image-20211211210517011.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SuR3Yup2-1642244354921)(实验报告.assets/image-20211211210559869.png)]

3、测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UoMJcf4G-1642244354922)(实验报告.assets/image-20211211193613269.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LLhzFOt3-1642244354922)(实验报告.assets/image-20211211193837851.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9DJgtTEw-1642244354923)(实验报告.assets/image-20211211193956973.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AusxIR4U-1642244354924)(实验报告.assets/image-20211211194028451.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GKDVGLej-1642244354924)(实验报告.assets/image-20211211194136784.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t5Y8ZV37-1642244354925)(实验报告.assets/image-20211211194239877.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W7wKsD1y-1642244354926)(实验报告.assets/image-20211211194325727.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xJAjgCI7-1642244354927)(实验报告.assets/image-20211211194443948.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8VLLaqOu-1642244354928)(实验报告.assets/image-20211211194553130.png)]

(更详细的内容以及代码部分见分享的资料吧,文章开头部分说明了获取方式)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
操作系统实验主要涉及进程互斥问题。在多道程序设计中,多个进程可能会同时访问共享资源。如果这些进程没有进行合理的协调和同步,就会出现互斥问题。互斥问题的解决方案包括:信号量、互斥锁、条件变量等。 在本次实验中,我们可以采用信号量来解决进程互斥问题。具体步骤如下: 1. 定义共享资源:在本实验中,我们可以定义一个临界区,多个进程需要访问该临界区。 2. 定义信号量:定义一个二元信号量,初始值为 1,用于表示当前临界区是否可用。 3. 进程同步:当一个进程需要访问临界区时,它需要先使用_matrix.scale(scale); break; } } m_bone_matrixes[i][bone_id * 3 + 0] = bone_matrix; } } update(); } } private: struct Mesh { GLuint vao; GLuint vbo_vertices; GLuint vbo_normals; GLuint vbo_tex_coords; GLuint vbo_bone_weights; GLuint vbo_bone_indices; int num_vertices; }; void createBoneHierarchy(const aiNode *node, const QMatrix4x4 &parent_transform) { QMatrix4x4 transform; transform.translate(QVector3D(node->mTransformation.a4, node->mTransformation.b4, node->mTransformation.c4)); transform *= parent_transform; if (m_bone_mapping.contains(QString::fromStdString(node->mName.C_Str()))) { int bone_id = m_bone_mapping.value(QString::fromStdString(node->mName.C_Str())); m_bone_offset_matrices[bone_id] = m_global_inverse_transform.inverted() * transform * m_bone_offset_matrices[bone_id]; } for (unsigned int i = 0; i < node->mNumChildren; ++i) { createBoneHierarchy(node->mChildren[i], transform); } } QOpenGLShaderProgram m_program; QVector<Mesh> m_meshes; QHash<QString, int> m_bone_mapping; QVector<QMatrix4x4> m_bone_offset_matrices; QVector<QVector<QMatrix4x4>> m_bone_matrixes; QMatrix4x4 m_global_inverse_transform; QElapsedTimer m_timer; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QSurfaceFormat format; format.setDepthBufferSize(24); format.setStencilBufferSize(8); format.setVersion(3, 3); format.setProfile(QSurfaceFormat::CoreProfile); QSurfaceFormat::setDefaultFormat(format); GLWidget w; w.show(); return a.exec(); } ``` 这个示例代码中,Assimp 负责加载模型数据和骨骼动画数据,并将它们转换为 OpenGL 用的数据格式。OpenGL 用着色器程序进行渲染,其中包括了骨骼矩阵数组的 uniform 变量,用于在 GPU 中计算顶点位置。每一帧都需要更新骨骼矩阵数组,并重新绘制场景。 需要注意的是,上面的代码中只是一个简单的示例,实际应用中需要更多的优化和错误处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陌兮_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值