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

📄 filsys.cpp

📁 大型实验:Unix文件管系统模拟。用内存中的一段区域模拟硬盘空间
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	/*改变当前目录表*/
	fseek(fd,DATASTART+cur_path_inode->di_addr[0]*BLOCKSIZ,0);
	fread(&dir.direct[0], BLOCKSIZ, 1, fd);

	return 1;
}

__int8 _rmdir(char* dirname)
{
	__int16 dinodeid,i;
    struct inode * inode;
	struct dir ndir;

    dinodeid = namei(dirname);
    if(dinodeid != -1){
		inode = iget(dir.direct[dinodeid].d_ino);
		if(_faccess(user_id,inode,DIMODE_WRITE)==0)/*没有权限*/
		{
			iput(inode);
			printf("\ncreate access not allowed \n");
			return 0;
		}
		if(inode->di_mode & DIMODE_FILE)
		{
			iput(inode);
			return _fdelete(dirname);
		}

		//	删除其下的子目录和文件
		fseek(fd,DATASTART+inode->di_addr[0]*BLOCKSIZ,0);
		fread(&ndir.direct[0],BLOCKSIZ,1,fd);
		ndir.size = (__int16)(inode->di_size/DIRSIZ);
		for(i=ndir.size-1; i>1; --i)
		{
			_rmdir(dir.direct[i].d_name);	
		}

		/*删除该目录的磁盘空间*/
		bfree(inode->di_addr[0]);


		//将该文件或是目录的后续文件或是目录迁移
		dir.size--;
		for(i = dinodeid; i<dir.size; ++i)
		{
			dir.direct[i].d_ino = dir.direct[i+1].d_ino;
			strcpy(dir.direct[i].d_name,dir.direct[i+1].d_name);
		}
		inode->di_number--;
			
		/*	free the mode in the memory */
		if (inode->i_forw == NULL){/*该节点为最后一个节点*/
			if(hinode[inode->i_ino%NHINO].i_forw == inode)
			{	
				/*该节点也是为第一个节点*/
				hinode[inode->i_ino%NHINO].i_forw = NULL;
			}
			else{
				inode->i_back->i_forw = NULL;
			}		
		}
		else{
			if(hinode[inode->i_ino%NHINO].i_forw == inode)
			{
				/*该节点是为第一个节点*/
				hinode[inode->i_ino%NHINO].i_forw = inode->i_forw;
				inode->i_back->i_forw = inode->i_forw;
			}
			else{
				inode->i_forw->i_back = inode->i_back;
				inode->i_back->i_forw = inode->i_forw;				
			}
		}
		ifree(inode);
		return 1;
	}
	return 0;
}


/*-------------------------------------------
format()
	格式化
	check:7-12 18:28
-------------------------------------------*/
void format()
{
	struct inode * inode;	/*i节点*/
	struct direct dir_buf[BLOCKSIZ / (DIRSIZ+2)];
	struct pwd passwd [BLOCKSIZ/PWDSIZ];

//	struct super_block filsys;
	unsigned __int16 block_buf[BLOCKSIZ / sizeof (__int16)];
	char * buf;
	__int16 i, j;

	/*	creat the file system file */
	fd = fopen (fsystemname, "wb");/*读写创建一个二进制文件*/
	if(fd==NULL)
	{
		printf ("\nfile system file creat failed! \n");
		exit(0);
	}
	buf=(char * ) malloc ((DINODEBLK+FILEBLK+2) * BLOCKSIZ * sizeof(char));
	if (buf==NULL)
	{
		printf ("\nfile system file creat failed! \n");
		exit(0);
	}

	/*设置磁盘空间中的数据为0*/
	memset(buf, '0', (DINODEBLK+2) * BLOCKSIZ);

//	fseek(fd,0, SEEK_SET);
	fwrite(buf,sizeof(char), (DINODEBLK+FILEBLK+2) * BLOCKSIZ * sizeof(char) ,fd);

	/* init the hinode*/
	for(i=0; i<NHINO; i++)
	{
		hinode[i].i_forw=NULL;
	}

	/*	1.creat the main directory and its sub dir etc and the file password */
	inode=iget(0);	/* 0 empty dinode id */
	inode->di_mode	= DIMODE_SHARE;
	inode->di_number = 1;
	iput(inode);

	inode=iget(1);    /* 1 main dir id */
	inode->di_number= 1;
	inode->di_mode = DIMODE_SHARE |DIMODE_DIR;
	inode->di_size = 3*(DIRSIZ+2);
	inode->di_addr[0]=0;    /* block 0tfl is used by the main directory */
	strcpy(dir_buf[0].d_name, "..");
	dir_buf[0].d_ino= 1;
	strcpy(dir_buf[1].d_name,".");
	dir_buf[1].d_ino= 1;
	strcpy(dir_buf[2].d_name, "etc");
	dir_buf[2].d_ino = 2;
	fseek(fd, DATASTART, SEEK_SET);
	fwrite(dir_buf, 3*(DIRSIZ+2), 1, fd);
	iput(inode);

	inode=iget(2);/* 2 etc dir id */
	inode ->di_number = 1;
	inode->di_mode = DIMODE_ADMIN|DIMODE_DIR;
	inode->di_size = 3*(DIRSIZ+2);
	inode->di_addr[0]=0;    /* block 0# is used by the etc */
	strcpy (dir_buf[0].d_name, "..");
	dir_buf[0].d_ino = 1;
	strcpy(dir_buf[1].d_name, ".");
	dir_buf[1].d_ino = 2;
	strcpy(dir_buf[2].d_name, "password");
	dir_buf[2].d_ino = 3;
	fseek(fd, DATASTART+BLOCKSIZ, SEEK_SET);
	fwrite (dir_buf, 1, 3*(DIRSIZ+2),fd);
	iput(inode);

	/*初始化用户和密码*/
	passwd[0].p_uid= 1; passwd[0].p_gid = GRUP_0; //管理员
	strcpy(passwd[0].username, "wangjianyou");
	strcpy(passwd[0].password, "20043188");

	passwd[1].p_uid= 2; passwd[1].p_gid = GRUP_1;
	strcpy(passwd[1].username, "shijie");
	strcpy(passwd[1].password, "20043185");

	passwd[2].p_uid= 3; passwd[2].p_gid = GRUP_1;
	strcpy(passwd[2].username, "chenchao");
	strcpy(passwd[2].password, "20043178");

	passwd[3].p_uid= 4; passwd[3].p_gid = GRUP_1;
	strcpy(passwd[3].username, "huangliyang");
	strcpy(passwd[3].password, "20043181");

	passwd[4].p_uid= 5; passwd[4].p_gid = GRUP_1;
	strcpy(passwd[4].username, "zhangjian");
	strcpy(passwd[4].password, "20043196");
	inode=iget(3);    /* 3 password id */
	inode->di_number = 1;
	inode->di_mode = DIMODE_ADMIN|DIMODE_FILE;
	inode->di_size = BLOCKSIZ;
	inode->di_addr[0]=2;
	for (i=5; i<PWDNUM; i++)
	{
		passwd[i].p_uid = 0;
		passwd[i].p_gid = GRUP_4;
		strcpy(passwd[i].password,"");
	}
	fseek(fd,DATASTART+2*BLOCKSIZ, SEEK_SET);
	fwrite(passwd, 1, BLOCKSIZ,fd);
	iput(inode);

	/*	2. initialize the superblock */
	filsys.s_isize = DINODEBLK;//i节点数目
	filsys.s_fsize=FILEBLK;//i节点区所站磁盘块数
	filsys.s_ninode=DINODEBLK * BLOCKSIZ/DINODESIZ-4;//空闲i节点数目
	filsys.s_nfree = FILEBLK-3;//空闲磁盘块数目

	for (i=0; i<NICINOD; i++)
	{
		/*	begin with 4. 0,1.2,3, is used by main, etc, password */
		filsys.s_inode[i] = 4+i;
	}
	filsys.s_pinode = 0;
	filsys.s_rinode = NICINOD+4;
	/*FILEBLK+1 is a flag of end */
	block_buf[NICFREE] = FILEBLK;//最后一块设为512

	for(i=FILEBLK; i>50; )
	{
		i -= 50;
		for(j = 0; j<NICFREE+1; ++j)
		{
			block_buf[j] = i+j;
		}
		fseek(fd ,DATASTART+BLOCKSIZ * i , SEEK_SET);
		fwrite(block_buf, 1, BLOCKSIZ,fd);
	}

	j = 0;
	for (; i>2; i--)
	{
		filsys.s_free[j] = i;
		j++;
	}

	filsys.s_pfree = j-1;
	filsys.s_pinode = 0;

	fseek(fd, BLOCKSIZ, 0);
	fwrite (&filsys,sizeof(struct super_block), 1,fd);
	fclose(fd);

}

/*---------------------------------------
halt()
	退出程序
---------------------------------------*/
void halt()
{
	__int16 i, j;
	__int16 block;

	/* 1.write back the current dir */
	block = cur_path_inode->di_addr[0];
	fseek(fd,DATASTART+block*BLOCKSIZ,0);
	fwrite(&dir.direct[0],BLOCKSIZ,1,fd);

	/*i节点数据写入i节点区*/

	cur_path_inode->i_flag = 0;
	cur_path_inode->di_size = dir.size*16;
	fseek(fd,DINODESTART+cur_path_inode->i_ino*DINODESIZ,0);
	fwrite(&cur_path_inode->di_number,DINODESIZ,1,fd);
	

	iput (cur_path_inode);

	/* 2.free the u_ofile and sys_ofile and inode */
	for (i=0; i<USERNUM; i++)
	{
		if (user[i].u_uid !=0)
			{
				for	(j=0; j<NOFILE; j++)
					{
						if (user[i].u_ofile[j]!=SYSOPENFILE+1)
							{
								_fclose(user[i].u_ofile[j]);
								user[i].u_ofile[j] = SYSOPENFILE+1;
							}
					}
			}
	}

	/*	3.write back the filesys to the disk */
	fseek(fd, BLOCKSIZ, SEEK_SET);
	fwrite(&filsys, sizeof(struct super_block), 1, fd);

	/* 4. close the file system column */
	fseek(fd, (2+32+512)*BLOCKSIZ, SEEK_SET);
	fclose(fd);
}


/*----------------------------------------
ialloc()
  请求i节点
  check : 7-12 19:00
----------------------------------------*/
struct inode * ialloc()
{
	struct inode * temp_inode;
	unsigned _int16 cur_di;
	_int16 i, block_end_flag;
	unsigned _int16 count;
	static struct dinode block_buf[BLOCKSIZ/DINODESIZ];

	/*判断当前i节点数组是否用完*/
	if (filsys. s_pinode == NICINOD)/*over*/
	{
		i=0;
		count = 0;
		block_end_flag= 1;
		filsys.s_pinode=NICINOD;
		cur_di = filsys.s_rinode;/*记录下一个i节点数组的下一个开始位置*/
		/*新请求i节点数组*/
		while ((count <NICINOD) || (count <= filsys.s_ninode))
		{
			if (block_end_flag)
			{
				/*当i节点区读取到最后位置时应再从开始位置开始查找*/
				if((DINODESTART+cur_di*DINODESIZ) >= DATASTART)/*Add by wjy: if*/
				{
					cur_di = 0;
				}
				/*读一组i节点*/
				fseek(fd,DINODESTART+cur_di*DINODESIZ,SEEK_SET);
				fread(block_buf, 1,BLOCKSIZ,fd);
				block_end_flag=0;
				i=0;
			}
			while (i<BLOCKSIZ/DINODESIZ  && (block_buf[i].di_mode != DIMODE_EMPTY))/*modify by wjy : while (block_buf[i].di_mode != DIEMPTY) */
			{
				cur_di++;
				i++;
			}
			if (i == BLOCKSIZ/DINODESIZ)
				block_end_flag=1;
			else
			{
				filsys.s_inode[--filsys.s_pinode]= cur_di;
				count++;
			}
		}
		filsys.s_rinode = cur_di;
	}

#if DEBUG 
	printf("%d\n",filsys.s_inode[filsys.s_pinode]);
#endif


	temp_inode = iget(filsys.s_inode[filsys.s_pinode]);
	fseek(fd, DINODESTART+filsys.s_inode[filsys.s_pinode]* DINODESIZ,SEEK_SET);
	fwrite (&temp_inode->di_number,1,sizeof(struct dinode), fd);
	++filsys.s_pinode;
	--filsys.s_ninode;
	filsys.s_fmod = SUPDATE;

	return temp_inode;
}


/*----------------------------------------
ifree 
	释放i节点
	check : 7-12 19:00
-----------------------------------------*/
void ifree(struct inode* pinode)	 
{

	if(pinode==NULL)
		return;

	++filsys.s_ninode;
	if (filsys.s_pinode != 0)    /* notfull */
	{
		--filsys.s_pinode;
		filsys.s_inode[filsys.s_pinode] = pinode->i_ino;
	}
	else /* full */
	{
		if (pinode->i_ino < filsys.s_rinode)
		{
			filsys.s_inode[NICINOD-1] = pinode->i_ino;
			filsys.s_rinode = pinode->i_ino;
		}
	}
	free(pinode);

}


/*----------------------------------
 iget()
 获得i节点
----------------------------------*/
struct inode * iget (unsigned __int16 dinodeid)    /* iget( ) */
{
	unsigned __int16 existed=0, inodeid;
	long addr;	
	struct inode *temp, * newinode;

	if(dinodeid<=0 || dinodeid>=BLOCKSIZ)
		dinodeid = 1;

	inodeid=dinodeid % NHINO;
	if (hinode[inodeid].i_forw==NULL){
		existed = 0;
	}
	else
	{
		temp = hinode[inodeid].i_forw;
		while (temp)
		{
			if (temp->i_ino == inodeid)/*existed */
			{
				existed = 1;
				temp->i_count ++;
				return temp;
			}
			else    /*not existed */
				temp =temp->i_forw;
		}
	}

	/*	1. calculate the addr of the dinode in the file sys column */
	addr = DINODESTART + dinodeid * DINODESIZ;

	/*	2. malloc the new mode */
	newinode = (struct inode *)malloc(sizeof (struct inode));

	/*	3.read the dinode to the mode */
	fseek(fd, addr, SEEK_SET);
	fread (&(newinode ->di_number), DINODESIZ, 1, fd);

	/* 4.put it __int16o hinode[inodeid] queue */
	newinode->i_forw = hinode[inodeid].i_forw;
	newinode->i_back = newinode;
	if(newinode->i_forw){
		newinode->i_forw->i_back = newinode;
	}	
	hinode[inodeid].i_forw = newinode;
	
	/* 5.initialize the mode */
	newinode->uf_id = -1;
	newinode->i_count = 1;
	newinode->i_flag = 0;    /* flag for not update */
	newinode->i_ino = dinodeid;
	return newinode;
}

/*----------------------------------
 iput()
 释放i节点
----------------------------------*/
void iput(struct inode * pinode) 
{
	long addr;
	__int16 block_num;
	__int16 i;
	if (pinode->i_count>1)
	{
		pinode->i_count--;
		if(pinode->i_flag==IUPDATE)
		{
			/*write back the mode */
			addr =DINODESTART + pinode->i_ino * DINODESIZ;
			fseek(fd, addr, SEEK_SET);
			fwrite (&pinode->di_number, DINODESIZ, 1 ,fd);
			pinode->i_flag = 0;
		}	
		return;
	}
	else
	{
		if (pinode->di_number == 0)
		{
			/*	rm the mode & the block of the file in the disk */
			block_num = (__int16)pinode->di_size/BLOCKSIZ;
			for(i=0; i<block_num; i++)
			{
				bfree(pinode->di_addr[i]);
			}
			ifree(pinode);
		}
		else /*pinode->di_number == 0*/
		{
			/*write back the mode */
			addr =DINODESTART + pinode->i_ino * DINODESIZ;
			fseek(fd, addr, SEEK_SET);
			fwrite (&pinode->di_number, DINODESIZ, 1 ,fd);
		}

		/*	free the mode in the memory */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -