📄 directory.cc
字号:
///////////////////////////////////////////////////////////////FileName : directory.cc////Creator : Fang Wenbin (0410706)//CreateTime : 2006-12-26////File Desc:// 1. The basis of whole file system// 2. Provide fundational operations of file and directory.////////////////////////////////////////////////////////////#include "copyright.h"#include "utility.h"#include "filehdr.h"#include "directory.h"#include "system.h"//////////////////////////////////////////////////////// Function name : Directory::Directory// Creator : Fang Wenbin(0410706)// CreateTime : 2007-1-8 20:54:09//// Function Desc : Constructor of Directory// The steps of Directory::Directory// Open an exsit file or directory.// Usually, we will open a directory as a parent // directory for a file.Then we operate file based// on the parent directory. // if the file isn't existed, variable error will// be set to true.// Fails if:// the file will be opened isn't existed.// Note : // Return type :// Argument : char *parentDir//////////////////////////////////////////////////////Directory::Directory(char *parentDir){ error = false; if (parentDir == NULL) { dirHdr = NULL; dirPath = NULL; }//end if (parentDir == NULL) else { dirPath = new char[s_FILE_NAME_MAX_LEN]; strcpy(dirPath, parentDir);////// Because the root directory has no directory entry,/// we must distinguish the root from other file or dirs./// if (!strcmp(parentDir, "/")) { dirHdrIndex = 0; dirHdr = new FileHeader; dirHdr->FetchFrom(s_SUPER->firstInodeBlock, 0); }//end if (!strcmp(parentDir...)) else { dirHdr = s_FindInode(parentDir); if (dirHdr == NULL) error = true; }//end if (!strcmp...) else }// s_Error();}//////////////////////////////////////////////////////// Function name : Directory::s_CreateRoot// Creator : Fang Wenbin(0410706)// CreateTime : 2007-1-8 21:04:13//// Function Desc : Create the root directory.// The steps of Directory::s_CreateRoot// 1.create an inode for root directory// 2.write the imap//// Fails if://// Note : This function is a static function,// which can only be used in the // filesys class' constructor.// Return type : void // Argument : s_SuperBlock *super//////////////////////////////////////////////////////void Directory::s_CreateRoot(s_SuperBlock *super){ FileHeader *inode = new FileHeader; inode->numBytes = 0; inode->s_fileMode = s_DIR_TYPE | s_DIR_ONE; inode->WriteBack(super->firstInodeBlock, 0); delete inode; s_Bitmap *imap = new s_Bitmap(4096); imap->FetchFrom(super->firstImapBlock, 4); imap->Mark(0); imap->WriteBack(super->firstImapBlock, 4); delete imap;}//////////////////////////////////////////////////////// Function name : Directory::s_Error// Creator : Fang Wenbin(0410706)// CreateTime : 2007-1-8 21:07:29//// Function Desc : Error Handler.// The steps of Directory::s_Error// Judge error's value. If error equals true, then// halt the machine. //// Fails if:// // Note : This function appears in almost
// every functions in this class.
// Return type : void
//////////////////////////////////////////////////////
void Directory::s_Error(){ if (error) { printf("error path!!\n"); currentThread->Finish(); }}
//////////////////////////////////////////////////////
// Function name : Directory::s_CreateDir
// Creator : Fang Wenbin(0410706)
// CreateTime : 2007-1-8 21:09:44
//
// Function Desc : Create an ordinary directory(non-root).
// The steps of Directory::s_CreateDir
// 1. Setup directory entry.
// 2. Setup inode.
// 3. Write Back inode.
// 4. Setup imap.
// 5. Write back directory entry.
// 6. Setup zmap.
//
// Fails if:
// 1. dirName's length is greater than 14
// 2. there is already a same name dir in parent dir.
//
// Note :
// Return type : void
// Argument : char *dirName
//////////////////////////////////////////////////////
void Directory::s_CreateDir(char *dirName){ s_Error();
if (strlen(dirName) > s_FILE_NAME_MAX_LEN)
{ error = true;
s_Error();
return; }
///
/// Check if exist a same name dir.
/// if (s_FindIndex(dirHdr, dirName) != -1)
{
error = true;
s_Error(); return; }
///
/// Set directory's level
/// short imode = s_DIR_TYPE; if (dirHdr->s_fileMode & s_DIR_ONE) imode |= s_DIR_TWO; if (dirHdr->s_fileMode & s_DIR_TWO) imode |= s_DIR_THREE; else if (dirHdr->s_fileMode & s_DIR_THREE) imode |= s_DIR_FOUR; else if (dirHdr->s_fileMode & s_DIR_FOUR) /*error handle*/; FileHeader *inode = new FileHeader; s_DirEntry *newDir = new s_DirEntry; s_Bitmap *zMap = new s_Bitmap(16384); s_Bitmap *iMap = new s_Bitmap(4096); zMap->FetchFrom(s_SUPER->firstZmapBlock, 16); iMap->FetchFrom(s_SUPER->firstImapBlock, 4); int iNum = iMap->Find(); if (iNum == -1) return; newDir->s_inodeIndex = iNum; strcpy(newDir->s_name, dirName); inode->s_fileMode = imode; inode->numBytes = 0; dirHdr->s_Allocate(zMap, (char*)newDir, 16); dirHdr->WriteBack(s_SUPER->firstInodeBlock+dirHdrIndex/4, dirHdrIndex%4); inode->WriteBack(s_SUPER->firstInodeBlock+newDir->s_inodeIndex/4, newDir->s_inodeIndex%4); zMap->WriteBack(s_SUPER->firstZmapBlock, 16); iMap->WriteBack(s_SUPER->firstImapBlock, 4); delete inode; delete newDir; delete iMap; delete zMap;}
//////////////////////////////////////////////////////
// Function name : Directory::s_CreateFile
// Creator : Fang Wenbin(0410706)
// CreateTime : 2007-1-8 21:15:59
//
// Function Desc : Create file.
// The steps of Directory::s_CreateFile
// 1. Setup directory entry.
// 2. Setup inode.
// 3. Write Back inode.
// 4. Setup imap.
// 5. Write back directory entry.
// 6. Setup zmap.
//
// Fails if:
// 1. fileName is greater than 14
// 2. there is already a same name file in this dir.
//
// Note :
// Return type : void
// Argument : char *fileName
//////////////////////////////////////////////////////
void Directory::s_CreateFile(char *fileName){ s_Error(); if (strlen(fileName) > s_FILE_NAME_MAX_LEN) {
error = true;
s_Error();
return;
} if (s_FindIndex(dirHdr, fileName) != -1) return; short imode = s_FILE_TYPE; FileHeader *inode = new FileHeader; s_DirEntry *newDir = new s_DirEntry; s_Bitmap *zMap = new s_Bitmap(16384); s_Bitmap *iMap = new s_Bitmap(4096); zMap->FetchFrom(s_SUPER->firstZmapBlock, 16); iMap->FetchFrom(s_SUPER->firstImapBlock, 4); int iNum = iMap->Find(); if (iNum == -1) return; newDir->s_inodeIndex = iNum; strcpy(newDir->s_name, fileName); inode->s_fileMode = imode; inode->numBytes = 0; dirHdr->s_Allocate(zMap, (char*)newDir, 16); dirHdr->WriteBack(s_SUPER->firstInodeBlock+dirHdrIndex/4, dirHdrIndex%4); inode->WriteBack(s_SUPER->firstInodeBlock+newDir->s_inodeIndex/4, newDir->s_inodeIndex%4); zMap->WriteBack(s_SUPER->firstZmapBlock, 16); iMap->WriteBack(s_SUPER->firstImapBlock, 4); delete inode; delete newDir; delete iMap; delete zMap; return;}
//////////////////////////////////////////////////////
// Function name : Directory::s_FindIndex
// Creator : Fang Wenbin(0410706)
// CreateTime : 2007-1-8 21:17:41
//
// Function Desc : Find file's inode index.
// The steps of Directory::s_FindIndex
// 1.search according parent dir's inode in direct index
// 2.search in first indirect index if necessary.
// 3.search in second indirect index if necessary.
// 4.search in third indirect index if necessary.
//
// Fails if:
// can't find the inode index of file
// Note :
// Return type : int --if fail, return -1
// Argument : FileHeader *inode --parent dir's inode
// Argument : char *fileName
//////////////////////////////////////////////////////
int Directory::s_FindIndex(FileHeader *inode, char *fileName){ s_Error(); char direct = 0; char first = 0; char second = 0; char third = 0; int lastSlot = inode->numBytes / 128; int maxDirect = 3; int maxFirst = maxDirect + 32; int maxSecond = maxFirst + 32*32; int maxThird = maxSecond + 32*32*32;
///
/// determine which level of index we need
/// if (lastSlot < 3) direct = 1; else if (lastSlot < maxFirst) direct = first = 1; else if (lastSlot < maxSecond) direct = first = second = 1; else if (lastSlot < maxThird) direct = first = second = third = 1; s_DirEntry *entryBuf = new s_DirEntry; int index = -1; int leftSize = inode->numBytes;
///
///Direct index search
///
if (direct == 1) { for (int i = 0; i < 3 && leftSize > 0; i++) { int slot = inode->s_dataSectors[i]; for (int j = 0; j < 128 && leftSize > 0; j+=16, leftSize-=16) { synchDisk->s_ReadDataInSector(slot, j, 16, (char*)entryBuf); if (!strcmp(entryBuf->s_name, fileName)) { index = entryBuf->s_inodeIndex; delete entryBuf; return index; }//end if (!strcmp...) }//end for (int j = 0; j < 128...) }//end for (int i = 0; i < maxDirect...) }//end if (direct == 1)
///
/// First indirect index search
/// if (first == 1) { int firstAddrs[32]; synchDisk->s_ReadDataInSector(inode->s_dataSectors[3], 0, 128, (char*)firstAddrs); for (int i = 0; i < 32 && leftSize > 0; i++) { int slot = firstAddrs[i]; for (int j = 0; j < 128 && leftSize > 0; j+= 16, leftSize-=16) { synchDisk->s_ReadDataInSector(slot, j, 16, (char*)entryBuf); if (!strcmp(entryBuf->s_name, fileName)) { index = entryBuf->s_inodeIndex; delete entryBuf; return index; }//end if (!strcmp... }//end for (int j = 0;...) }//end for (int i = 0; ...) }//end if (first == 1)
///
/// Second indirect index search
/// if (second == 1) { int secondAddrs[32]; int secondMidAddrs[32]; synchDisk->ReadSector(inode->s_dataSectors[4], (char*)secondMidAddrs); for (int k = 0; k < 32 && leftSize > 0; k++) { synchDisk->ReadSector(secondMidAddrs[k], (char*)secondAddrs); for (int j = 0; j < 32 && leftSize > 0; j++) { for (int i = 0; i < 128 && leftSize > 0; i+=16, leftSize-= 16) { synchDisk->s_ReadDataInSector(secondAddrs[j], i, 16,(char*)entryBuf); if (!strcmp(entryBuf->s_name, fileName)) { index = entryBuf->s_inodeIndex; delete entryBuf; return index;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -