日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

操作系统课设实验五---Nachos文件系统扩展

發(fā)布時間:2023/12/10 windows 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 操作系统课设实验五---Nachos文件系统扩展 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這次的實驗讓我想起了上學(xué)期被操作系統(tǒng)的九個實驗支配的恐懼,因為這次可能也是前五次試驗中最難的一次了,讀源碼加實現(xiàn)花了可能一兩天的時間,所以也有必要記錄一下,有些地方做的不是很好,比如Makefile自己寫的話可能不需要把所有文件都從filesys復(fù)制到lab5,可是我太菜做不到,所以先這樣湊合著吧emmm,畢竟還有一堆其他實驗。

一、實驗要求重述

目標(biāo)

在lab5目錄下,通過對nachos源代碼的修改,實現(xiàn)可擴展的文件系統(tǒng),即滿足以下需求

  • 當(dāng)一個文件創(chuàng)建的時候,它的初始大小為0
  • 文件的大小可以在文件內(nèi)容增加時改變

如:100 bytes大小的文件在50 bytes的位置往后再寫100個byte,文件大小變?yōu)?50 bytes.

設(shè)計與實現(xiàn)的提示

  • 在lab5目錄下進行工作,其下的test文件夾中存放著測試文件。
  • 需要創(chuàng)建arch子目錄以及自己的Makefile文件到lab5。
  • 考慮filesys中的哪些文件需要拷貝到lab5下并進行修改。
  • 不需要修改lab5目錄下的main. cc,但是需要將fstest.cc中的Append與NAppend函數(shù)中幾行注釋取消掉:
  • // Write the inode back to the disk, because we have changed it // openFile->WriteBack(); // printf("inodes have been written back\n");

    取消最后兩行的注釋即可。此外,在取消注釋之后還需要在OpenFile的類中實現(xiàn)Writeback方法。

    二、分析

    首先我們需要分析nachos文件部分的源代碼,一方面是要了解那七個文件的用法,另一方面要閱讀測試使用的main. cc和fstest. cc,通過閱讀源碼,我們才能達(dá)到盡可能少的修改源碼來實現(xiàn)功能的目的。

    通過對這些源碼的閱讀以及實驗指導(dǎo)書的提示,首先我們需要修改OpenFile這個類,要實現(xiàn)它的WriteBack方法,這個方法的作用是將大小改變的文件頭信息寫回磁盤。其次在寫的方法上我們也要進行修改,那就是該類的WriteAt方法,而因為這里的邏輯是假設(shè)文件大小固定,因此我們需要為它添加一個申請新的磁盤空間的方法,這里我在OpenFile類新建了一個AllocateSpace方法。但在實際申請磁盤空間的時候,應(yīng)該需要在FileHeader類中進行,因此我們?yōu)槠湓黾右粋€ExtendSpace方法。最后,在文件大小變化的時候,應(yīng)該修改FileHeader類中的numBytes的值,因此我們需要添加一個set方法SetLength。這一切就緒之后,就可以依次實現(xiàn)這些方法了。

    ps:原來我在AllocateSpace方法中是直接先釋放所有磁盤空間再申請新空間來實現(xiàn)擴容的,經(jīng)過小伙伴指正我也發(fā)現(xiàn)這樣確實不行,如果內(nèi)容存儲扇區(qū)之前的扇區(qū)空間都被別的內(nèi)容占用的話的沒有問題,可是如果有空扇區(qū)的話,申請之后文件頭信息中指向的內(nèi)容扇區(qū)就會和實際存儲的扇區(qū)有偏差。
    至少之前的設(shè)計是有問題的,可以用以下命令實驗下試試

    rm DISK ./nachos -f ./nachos -cp test/big big ./nachos -cp test/small small ./nachos -r big ./nachos -ap test/small small ./nachos -D

    之前的結(jié)果:

    現(xiàn)在的結(jié)果

    三、實現(xiàn)

    首先來說FileHeader類中的SetLength方法,我們只需要簡單的設(shè)置即可,因此它的代碼也非常簡單,如下:

    void FileHeader::SetLength(int length) {this->numBytes=length; }

    下一步來實現(xiàn)相對簡單一點的OpenFile類中的WriteBack方法,這里我們要把其內(nèi)部的FileHeader類型的成員hdr寫回到磁盤中,FileHeader內(nèi)部實現(xiàn)了寫回磁盤的方法,但是它需要扇區(qū)參數(shù),而在這個OpenFile類中這個值并不好取得,因此我們再給OpenFile類增加一個私有成員sector,并在其構(gòu)造函數(shù)中利用傳入的頭信息扇區(qū)號來初始化。如下:

    OpenFile::OpenFile(int sector) { hdr = new FileHeader;hdr->FetchFrom(sector);seekPosition = 0;this->sector=sector; }

    這樣,我們就能在WriteBack方法中拿到扇區(qū)號了。如下:

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

    然后,我們就只剩下OpenFile類中的AllocateSpace與WriteAt函數(shù)和FileHeader類中的ExtendSpace函數(shù)需要完成了。

    由于OpenFile類里面的兩個函數(shù)的實現(xiàn)都需要使用到ExtendSpace函數(shù)的功能,因此這里首先來實現(xiàn)這個函數(shù),這個函數(shù)模仿Allocate函數(shù)實現(xiàn),需要做的就是根據(jù)要申請的空間大小和比特圖來申請新的磁盤扇區(qū)空間。如下:

    bool FileHeader::ExtendSpace(BitMap *freeMap,int appendSize) {int oriSectors=numSectors; //記錄原空間大小numSectors = divRoundUp(appendSize, SectorSize)+oriSectors; //計算新扇區(qū)大小 // printf("newSectorsNum is %d\n", numSectors);if (freeMap->NumClear() < numSectors-oriSectors){numSectors=oriSectors;//將空間大小復(fù)原return FALSE; // not enough space}for (int i = oriSectors; i < numSectors; i++) //申請新的扇區(qū)dataSectors[i] = freeMap->Find();return TRUE; }

    在WriteAt函數(shù)中需要調(diào)用AllocateSpace函數(shù),所以首先應(yīng)該來實現(xiàn)AllocateSpace函數(shù):
    這個函數(shù)的功能應(yīng)該是給它一個需要擴展的文件長度,它就能申請到這個長度對應(yīng)的扇區(qū)來進行以后的存儲,而具體的申請操作在OpenFile類的FileHeader類型的hdr成員已經(jīng)實現(xiàn)了,這里可以直接調(diào)用它來做:

    void OpenFile::AllocateSpace(int size) {BitMap *freeMap;freeMap=new BitMap(NumSectors); //新建一個BitMap對象OpenFile *freeMapFile;freeMapFile=new OpenFile(0); //新建一個比特圖對應(yīng)的OpenFile對象freeMap->FetchFrom(freeMapFile); //從磁盤中取出比特圖的信息hdr->ExtendSpace(freeMap,size); //實際的擴展操作freeMap->WriteBack(freeMapFile); //寫回比特圖的信息delete freeMap; }

    完成這些之后,可以來實現(xiàn)WriteAt方法了,這個方法在實現(xiàn)的時候已經(jīng)考慮到了不從頭開始寫的情況,因此我們也不需要太擔(dān)心ap和hap命令的實現(xiàn),在實現(xiàn)這個函數(shù)之前,我們應(yīng)該先進行一些思考:

    如果是cp模式,即直接復(fù)制UNIX文件的內(nèi)容到nachos文件系統(tǒng)中去,則當(dāng)前的代碼已經(jīng)不需要修改了。如果我們要實現(xiàn)ap或者h(yuǎn)ap模式,則需要申請新的空間,而剩余的部分也不需要進行修改,因此,我們首先需要判斷一下是不是追加模式,如果是,則去申請新的空間。而判斷是否為追加模式,我們可以用當(dāng)前文件指針的位置是否大于文件大小來確定。如果是追加模式,我們則分兩種情況討論:

    1.加上新的字符后的文件大小還沒有占滿整個扇區(qū),這時只需要設(shè)置文件大小即可。

    2.加上新的字符后文件大小已經(jīng)超過了整個扇區(qū),這時候就需要申請新的磁盤空間來對文件進行存儲了。

    此外再排除一些WriteAt本來的關(guān)于文件長度的一些限制之后,修改的WriteAt方法如下:

    int OpenFile::WriteAt(char *from, int numBytes, int position) {int fileLength = hdr->FileLength();int i, firstSector, lastSector, numSectors;bool firstAligned, lastAligned;char *buf; // printf("seekPosition is %d,fileLength is %d\n",seekPosition,fileLength);if (numBytes < 0) return 0; // check requestif(seekPosition>=fileLength) //如果文件指針已經(jīng)超過了文件大小{numSectors=divRoundUp(fileLength,SectorSize); //計算當(dāng)前需要的扇區(qū)int numPos=seekPosition+numBytes; //計算添加新字節(jié)之后的指針位置if(numPos>numSectors*SectorSize) //如果文件為空或者超過了已有扇區(qū)空間{AllocateSpace(numPos-numSectors*SectorSize);//申請新空間fileLength+=numBytes; //增大文件空間}hdr->SetLength(numPos); //根據(jù)新指針位置設(shè)置新的文件大小}//寫入的部分已經(jīng)考慮了從中間寫入的情況if(fileLength==0) return 0;DEBUG('f', "Writing %d bytes at %d, from file of length %d.\n", numBytes, position, fileLength);firstSector = divRoundDown(position, SectorSize);lastSector = divRoundDown(position + numBytes - 1, SectorSize);numSectors = 1 + lastSector - firstSector; // printf("firstSector is %d,lastSector is %d\n",firstSector,lastSector);buf = new char[numSectors * SectorSize];firstAligned = (bool)(position == (firstSector * SectorSize));lastAligned = (bool)((position + numBytes) == ((lastSector + 1) * SectorSize));// read in first and last sector, if they are to be partially modifiedif (!firstAligned)ReadAt(buf, SectorSize, firstSector * SectorSize); if (!lastAligned && ((firstSector != lastSector) || firstAligned))ReadAt(&buf[(lastSector - firstSector) * SectorSize], SectorSize, lastSector * SectorSize); // copy in the bytes we want to change bcopy(from, &buf[position - (firstSector * SectorSize)], numBytes);// write modified sectors backfor (i = firstSector; i <= lastSector; i++) synchDisk->WriteSector(hdr->ByteToSector(i * SectorSize), &buf[(i - firstSector) * SectorSize]);delete [] buf;return numBytes; }

    最后,我們則是按照實驗指導(dǎo)書上的提示,在fstest.cc文件中取消掉調(diào)用WriteBack的部分的注釋。

    // Write the inode back to the disk, because we have changed itopenFile->WriteBack();printf("inodes have been written back\n");

    源碼部分處理完成以后就要進行編譯與測試了,這里實驗要求自己編寫Makefile文件,由于nachos的編譯模塊過于復(fù)雜,這里我先把filesys中的所有除fstest.cc之外的文件復(fù)制到lab5目錄下,然后修改Makefile文件來實現(xiàn)的編譯,兩個相關(guān)的Makefile代碼如下:

    Makefile.local:

    ifndef MAKEFILE_LAB5_LOCAL define MAKEFILE_LAB5_LOCAL yes endef# Add new sourcefiles here.CCFILES +=bitmap.cc\directory.cc\filehdr.cc\filesys.cc\fstest.cc\openfile.cc\synchdisk.cc\disk.cc\main.ccifdef MAKEFILE_USERPROG_LOCAL DEFINES := $(DEFINES:FILESYS_STUB=FILESYS) else INCPATH += -I../userprog -I../lab5 DEFINES += -DFILESYS_NEEDED -DFILESYS endifendif # MAKEFILE_FILESYS_LOCAL

    Makefile:

    ifndef MAKEFILE_LAB5 define MAKEFILE_LAB5 yes endef# You can re-order the assignments. If filesys comes before userprog, # just re-order and comment the includes below as appropriate.include ../threads/Makefile.local include ../lab5/Makefile.local #include ../userprog/Makefile.local #include ../vm/Makefile.local #include ../filesys/Makefile.localinclude ../Makefile.dep include ../Makefile.commonendif # MAKEFILE_FILESYS

    這里有一個源碼中的坑,就是在測試要用的main.cc中,如果不改的話編譯會報如下錯誤:

    只需要進入lab5下的main. cc,把NAppend函數(shù)的聲明修改一下即可:

    extern void NAppend(char *from, char *to);

    四、測試

    測試可能需要若干命令,這里我們可以寫一個Shell腳本來保存連續(xù)的命令,需要的時候調(diào)用然后觀察最后結(jié)果即可,這里我準(zhǔn)備了兩個測試腳本,修改完源碼并且編譯之后執(zhí)行即可:

    測試ap參數(shù):

    rm DISK ./nachos -f ./nachos -cp test/small small ./nachos -ap test/small small ./nachos -cp test/empty empty ./nachos -ap test/medium empty ./nachos -D

    測試hap參數(shù):

    rm DISK ./nachos -f ./nachos -cp test/small small ./nachos -cp test/big big ./nachos -hap test/big small ./nachos -hap test/small big ./nachos -D

    將上述兩個腳本分別另存為ap. sh和hap. sh,然后在命令行中執(zhí)行如下命令給予其執(zhí)行權(quán)限:

    $chmod a+x ap.sh $chmod a+x hap.sh

    然后首先我們測試ap參數(shù)的運行情況,運行結(jié)果如下:

    可見,與實驗指導(dǎo)書預(yù)計的結(jié)果一致,即ap功能得以實現(xiàn)。

    接下來再來測試一下hap命令。

    這里測試了兩種情況,即從大文件的中間寫小文件和從小文件的中間寫大文件。結(jié)果如下:運行結(jié)果如下:

    從結(jié)果來看,hap的功能也得到了實現(xiàn)。

    五、結(jié)論分析與體會

    從輸出結(jié)果來看,拓展之后的文件系統(tǒng)在保證了基本的cp命令執(zhí)行不出錯的情況下,增加了ap和hap兩個命令,讓原來固定大小的文件系統(tǒng)變成了大小可變的文件系統(tǒng)。

    本次實驗在掌握了nachos基本文件命令用法的情況下,對其功能進行了拓展,增加了文件可變的功能,而實現(xiàn)這個功能的前提也是足夠了解nachos磁盤系統(tǒng)相關(guān)的源代碼,因此通過擴展這個功能,我對nachos文件系統(tǒng)相關(guān)的部分有了更深的認(rèn)識,也對操作系統(tǒng)中所講的文件系統(tǒng)相關(guān)的內(nèi)容進行了很好的回顧。

    總結(jié)

    以上是生活随笔為你收集整理的操作系统课设实验五---Nachos文件系统扩展的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。