之前搞錯的MP1-part2(error

bool
FileSystem::Create(char *name, int initialSize)
{
    Directory *directory;
    PersistentBitmap *freeMap;
    FileHeader *hdr;
    int sector;
    bool success;

    DEBUG(dbgFile, "Creating file " << name << " size " << initialSize);

    directory = new Directory(NumDirEntries);
    directory->FetchFrom(directoryFile);

    if (directory->Find(name) != -1)
      success = FALSE;                  // file is already in directory
    else {
        freeMap = new PersistentBitmap(freeMapFile,NumSectors);
        sector = freeMap->FindAndSet(); // find a sector to hold the file header
        if (sector == -1)
            success = FALSE;            // no free block for file header
        else if (!directory->Add(name, sector))
            success = FALSE;    // no space in directory
        else {
            hdr = new FileHeader;
            if (!hdr->Allocate(freeMap, initialSize))
                success = FALSE;        // no space on disk for data
            else {
                success = TRUE;
                // everthing worked, flush all changes back to disk
                hdr->WriteBack(sector);
                directory->WriteBack(directoryFile);
                freeMap->WriteBack(freeMapFile);
            }
            delete hdr;
        }
        delete freeMap;
    }
    delete directory;
    return success;
}

我先來講解一下creat的操作,首先可以看到Filesystem會去directory當中檢查file是否存在,若沒有才會去新增。接下來BitMap()是用來去Disk上操作的,主要是找到空間放置file header。得到空間位置會去檢查disk中有沒有free block,還有檢查directory中有沒有空間放置檔案(不同的os會有不同限制,傳統的unix會限制15...映像中是這樣,會在去查證一下),若是directory有空間放置檔案,救會將檔案名稱跟sector加入到directory當中。最後是新增一個file header,並且allocateu一塊disk空間存放file data,最後是將file寫入disk中(在unix中使用fflush指令可作到)。

再來是看一下我們最主要要使用到的FileSystem::Open(char *name)

OpenFile *
FileSystem::Open(char *name)
{ 
    Directory *directory = new Directory(NumDirEntries);
    OpenFile *openFile = NULL;
    int sector;

    DEBUG(dbgFile, "Opening file" << name);
    directory->FetchFrom(directoryFile);
    sector = directory->Find(name); 
    if (sector >= 0)         
    openFile = new OpenFile(sector);    // name was found in directory 
    delete directory;
    return openFile;                // return NULL if not found
}

Open主要是先得到sector,然後再去新增一個openfile的物件。我們主要就是透過openfile object來read和write檔案。然而我們可以透過回傳的openFile來進行操作。


那我們就回到ExceptionHandler去處理open的case

 case SC_Open:
                        val = kernel->machine->ReadRegister(4);
                        {
                        char *filename = &(kernel->machine->mainMemory[val]);
                        status = SysOpen(filename);
                        kernel->machine->WriteRegister(2, (int) status);//file address
                        }
                        kernel->machine->WriteRegister(PrevPCReg, kernel->machine->ReadRegister(PCReg));
                        kernel->machine->WriteRegister(PCReg, kernel->machine->ReadRegister(PCReg) + 4);
                        kernel->machine->WriteRegister(NextPCReg, kernel->machine->ReadRegister(PCReg)+4);
                        return;
                        ASSERTNOTREACHED();
                        break;

先將file name從register4讀取出來,再傳送給sysopen處理,最後我們會得到status(openfloe object的address),然後把需要return的參數寫入到register2當中。到這邊就結束open的exception處理。


SysOpen需要去kernel的system call中處理,開啟userprog/ksyscall.h,並加上

int SysOpen(char *filename)
{
        // return value
        // negtive: failed
        // larger than 0: openfilw object address
        return (int)&(kernel->interrupt->OpenFile(filename));
}

這主要是取得openfile object的address並且轉成integer。

results matching ""

    No results matching ""