?? filesystem.cpp
字號:
}
fseek(fd, 0, 0);
fread(&sb, 1, sizeof(SuperBlock), fd);
fseek(fd, BlockSize, 0);
fread(this->AllUser, 4, sizeof(User), fd);
int i;
for (i=0; i<NHINO; i++) {
hinode[i].iForw = NULL;
}
for (i=0; i<100; i++) {
sys_ofile[i].f_count = 0;
sys_ofile[i].f_inode = NULL;
sys_ofile[i].uid = -1;
}
}
void FileSystem::UnLoad() {
std::string str;
int i;
INode* inode;
for (i=0; i<this->LoginNum; i++) {
str = this->LoginUser[i].user.usn;
this->Logout(str.c_str());
}
for (i=0; i<NHINO; i++) {
inode = hinode[i].iForw;
while (NULL != inode) {
this->IPut(inode);
inode = inode->iForw;
}
}
/*
User usr;
fseek(fd, BlockSize, 0);
fread(&usr, 1, sizeof(User), fd);
// ddddddddddd
cout << usr.usn << endl;*/
this->SaveSuperBlock();
cout << "系統正常御載!" << endl;
}
void FileSystem::Format() {
int i;
FILE* fd = fopen(this->Disk_Name, "r+w+b");
BMap map;
for (int j=IBlockNum+2; j<1024; j+=50) {
for (i=1; i<50; i++) {
map.usemap[i] = 0;
map.BAddr[i] = 1 + (j+i);
map.FBNum = 49;
}
fseek(fd, j*BlockSize, 0);
fwrite(&map, 1, sizeof(BMap), fd);
}
DInode dinode;
dinode.mode = 0;
dinode.no = 1;
dinode.size = 0;
dinode.type = 'e';
for (i=0; i<IBlockNum*BlockSize/sizeof(DInode); i++) {
fseek(fd, this->IN_Start+i*sizeof(DInode), 0);
fwrite(&dinode, 1, sizeof(DInode), fd);
dinode.no++;
}
char* name[4] = {"alvin", "vica", "kzk", "doy"};
User user;
Direct dir;
dir.size = 0;
dinode.size = 1;
dinode.mode = 1;
dinode.type = 'd';
dinode.di_number = 1;
for (i=0; i<4; i++) {
dinode.addr[0] = IBlockNum + 2 + (i/49)*50 + i%49+1;
dinode.no = i+1;
fseek(fd, this->mapAddr(dinode.no), 0);
fwrite(&dinode, 1, sizeof(DInode), fd);
fseek(fd, this->Data_Start+(i+1)*BlockSize, 0);
fwrite(&dir, 1, sizeof(Direct), fd);
strcpy(user.usn, name[i]);
strcpy(user.pwd, name[i]);
user.Dino = i+1;
fseek(fd, BlockSize+i*sizeof(User), 0);
fwrite(&user, 1, sizeof(User), fd);
}
SuperBlock sb;
sb.DBNum = DBlockNum/50 * (this->GroupSize-1);
sb.IBNum = IBlockNum/50 * (this->GroupSize-1);
sb.FBNum = 12*49-4;
sb.FINum = IBlockNum*BlockSize/sizeof(DInode)-4;
sb.pFB = 0;
sb.pFI = 0;
sb.SysMod = 0;
fseek(fd, 0, 0);
fwrite(&sb, 1, sizeof(SuperBlock), fd);
fclose(fd);
}
int FileSystem::UNameI(const char *usn) {
for (int i=0; i<this->LoginNum; i++) {
if (strcmp(usn, this->LoginUser[i].user.usn) == 0) {
return i;
}
}
return -1;
}
unsigned int FileSystem::BAlloc() {
if (sb.FBNum == 0) {
cout << "磁盤以滿" << endl;
return 0;
}
if (sb.pFB == 0) {
int i, j;
int count = 0;
bool flag = 1;
for (i=0; i<DBlockNum/this->GroupSize; i++) {
BMap map;
fseek(fd, this->Data_Start + BlockSize*this->GroupSize*i, 0);
fread(&map, 1, sizeof(BMap), fd);
for (j=0; j<(this->GroupSize-1); j++) {
if (map.usemap[j] == 0) {
map.usemap[j] = 1;
sb.FBS[sb.pFB] = map.BAddr[j];
sb.pFB++;
map.FBNum--;
count++;
if (count == 50) {
flag = 0;
break;
}
}
}
fseek(fd, this->Data_Start + BlockSize*50*i, 0);
fwrite(&map, 1, sizeof(BMap), fd);
if (!flag) break;
}
}
unsigned int free_block = sb.FBS[sb.pFB-1];
sb.SysMod = 0;
sb.FBNum--;
sb.pFB--;
this->SaveSuperBlock();
return free_block;
}
void FileSystem::BFree(unsigned int block_num) {
int i;
int g, of;
unsigned int blk;
BMap map;
if (sb.pFB == 100) { // 棧滿
for (i=0; i<50; i++) {
blk = sb.FBS[sb.pFB-1];
sb.pFB--;
g = (blk-2) / 50;
of = (blk-2) % 50;
fseek(fd, BlockSize*blk, 0);
fread(&map, 1, sizeof(BMap), fd);
map.FBNum++;
map.usemap[of-1] = 0;
fwrite(&map, 1, sizeof(BMap), fd);
}
}
sb.FBS[sb.pFB] = block_num;
sb.pFB++;
sb.FBNum++;
sb.SysMod = 0;
this->SaveSuperBlock();
}
int FileSystem::Open(const char *usn, const char *name) {
if (!this->CheckLogin(usn)) return -1;
INode* inode;
int i;
unsigned int dinodeid = this->NameI(usn, name);
if (dinodeid == 0) {
cout << "文件不存在!" << endl;
return -1;
}
inode = this->IGet(dinodeid);
for (i=0; i<100; i++) {
if (sys_ofile[i].f_count == 0) break;
}
if (i == 100) {
cout << "系統當前打開太多文件,請稍后再試!" << endl;
return -1;
}
sys_ofile[i].f_inode = inode;
sys_ofile[i].f_count = 1;
sys_ofile[i].uid = this->UNameI(usn);
return i;
}
int FileSystem::CheckUserFile(const char *usn, int file) {
if (file<0 || file>99 || sys_ofile[file].f_count < 1) {
cout << "文件沒有被打開!" << endl;
return 0;
}
int uid = this->UNameI(usn);
if (sys_ofile[file].uid != uid) {
cout << "文件正被其它用戶打開!" << endl;
return 0;
}
return 1;
}
void FileSystem::Close(const char *usn, const int file) {
if (!this->CheckLogin(usn)) return;
if (!this->CheckUserFile(usn, file)) return;
sys_ofile[file].f_count = 0;
}
void FileSystem::Write(const char *usn, int file, const char *content) {
if (!this->CheckLogin(usn)) return;
if (!this->CheckUserFile(usn, file)) return;
INode* inode = sys_ofile[file].f_inode;
inode = this->IGet(inode->Dino);
std::string str = content;
int length = str.length();
char* buf = (char*)malloc(sizeof(char)*length + BlockSize);
int bNum = length / BlockSize;
int MR = length%BlockSize;
if (MR!=0) bNum++;
unsigned bAddr;
int i;
for (i=0; i<inode->size; i++) {
this->BFree(inode->addr[i]);
}
inode->size = bNum;
for (i=0; i<bNum; i++) {
bAddr = this->BAlloc();
inode->addr[i] = bAddr;
if (bAddr != 0) {
fseek(fd, bAddr*BlockSize, 0);
fwrite(content+i*BlockSize, 1, BlockSize, fd);
}
}
this->IPut(inode);
}
std::string FileSystem::Read(const char *usn, int file) {
std::string str;
if (!this->CheckLogin(usn)) {
str = "";
return str;
}
if (!this->CheckUserFile(usn, file)) {
str = "";
return str;
}
INode* inode = sys_ofile[file].f_inode;
inode = this->IGet(inode->Dino);
char* buf;
if (inode->size < 1) {
str = "";
} else {
buf = (char*)malloc(sizeof(char)*BlockSize*inode->size);
for (int i=0; i<inode->size; i++) {
fseek(fd, inode->addr[i]*BlockSize, 0);
fread(buf+BlockSize*i, 1, BlockSize, fd);
}
str = buf;
free(buf);
}
this->IPut(inode);
return str;
}
void FileSystem::DeleteFile(const char *usn, const char *name) {
if (!this->CheckLogin(usn)) return;
int i;
unsigned int dinodeid = this->NameI(usn, name);
if (dinodeid == 0) {
cout << "文件不存在!" << endl;
return;
}
INode* inode = this->IGet(dinodeid);
if (inode->type != 'f') {
this->IPut(inode);
cout << "文件不存在!" << endl;
return;
}
this->IPut(inode);
for (i=0; i<100; i++) {
if (sys_ofile[i].f_count>0 && sys_ofile[i].f_inode->Dino == dinodeid) {
cout << "文件正被打開,不能刪除!" << endl;
return;
}
}
unsigned int curDir = this->LoginUser[this->UNameI(usn)].CurDirInodeID;
inode = this->IGet(curDir);
Direct dir;
fseek(fd, inode->addr[0]*BlockSize, 0);
fread(&dir, 1, sizeof(Direct), fd);
for (i=0; i<dir.size; i++) {
if (dir.files[i].Dino == dinodeid) {
dir.size--;
dir.files[i] = dir.files[dir.size];
break;
}
}
fseek(fd, inode->addr[0]*BlockSize, 0);
fwrite(&dir, 1, sizeof(Direct), fd);
this->IPut(inode);
inode = this->IGet(dinodeid);
for (i=0; i<inode->size; i++) {
this->BFree(inode->addr[i]);
}
this->IPut(inode);
this->IFree(dinodeid);
cout << "文件刪除成功!" << endl;
}
void FileSystem::DeleteFolder(const char *usn, const char *name) {
if (!this->CheckLogin(usn)) return;
if (0 == strcmp("/", name)) return;
unsigned int dinodeid = this->NameI(usn, name);
if (dinodeid == 0) {
cout << "文件夾不存在!" << endl;
return;
}
INode* inode = this->IGet(dinodeid);
if (inode->type != 'd') {
this->IPut(inode);
cout << "文件夾不存在!" << endl;
return;
}
this->IPut(inode);
unsigned int curDir = this->LoginUser[this->UNameI(usn)].CurDirInodeID;
inode = this->IGet(curDir);
Direct dir;
fseek(fd, inode->addr[0]*BlockSize, 0);
fread(&dir, 1, sizeof(Direct), fd);
for (int i=0; i<dir.size; i++) {
if (dir.files[i].Dino == dinodeid) {
dir.size--;
dir.files[i] = dir.files[dir.size];
break;
}
}
fseek(fd, inode->addr[0]*BlockSize, 0);
fwrite(&dir, 1, sizeof(Direct), fd);
this->IPut(inode);
inode = this->IGet(dinodeid);
fseek(fd, inode->addr[0]*BlockSize, 0);
fread(&dir, 1, sizeof(Direct), fd);
this->BFree(inode->addr[0]);
this->IPut(inode);
this->IFree(dinodeid);
this->DeleteADir(dir);
cout << "文件夾刪除成功!" << endl;
}
void FileSystem::DeleteADir(Direct dir) {
INode *inode, *tinode;
unsigned int dinodeid, dnid;
Direct sdir;
int j;
for (int i=0; i<dir.size; i++) {
dinodeid = dir.files[i].Dino;
inode = this->IGet(dinodeid);
if (inode->type == 'f') {
for (j=0; j<inode->size; j++) {
this->BFree(inode->addr[j]);
}
this->IPut(inode);
this->IFree(dinodeid);
} else if (inode->type == 'd') {
if (strcmp("..", dir.files[i].name)!=0) {
this->IPut(inode);
this->IFree(dinodeid);
dnid = dir.files[i].Dino;
tinode = this->IGet(dnid);
fseek(fd, tinode->addr[0]*BlockSize, 0);
fread(&sdir, 1, sizeof(Direct), fd);
this->BFree(tinode->addr[0]);
this->IPut(tinode);
this->IFree(dnid);
this->DeleteADir(sdir);
} else {
this->IPut(inode);
this->IFree(dinodeid);
}
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -