⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filesystem.cpp

📁 LINUX 设计一个简单的二级文件系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	}
	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 + -