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

📄 fs.c

📁 模拟linux操作系统文件系统资源管理的C程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	 * 入口参数:待写文件的inode 指针
	 * 出口参数:写文件成功与否的信息
	 * 函数功能:往已打开文件写内容
	 *********************************************/
	 unsigned int twrite(struct inode * pnode,const char * buf,  unsigned int len, unsigned int mode)
	{ 
		  unsigned int i,freeblk,pblk;
		  unsigned int offset,rwx;
		//struct inode * pn


		/** read out super  block area at first **/
		if(psp==NULL){	//第一次进入则需读出 super block 结构
			psp=(struct super_block *)malloc(sizeof(struct super_block));
			if(psp==NULL){
				printf("Initiate global variable psp error! \n");
				return MAL_ERR;
			}
			/* read out super block */
			fread(psp,sizeof(struct super_block),1,fd);
		}

		/* user check */
		i=cur_usernum;
		if(pnode->i_uid!=psp->users[i].uid){
			printf("User illegal!");
			return PRI_ERR;	
		}

		/* file mode check */
		rwx=pnode->i_mode.rwx;
		if(((rwx<<1)>>2)==0){
			printf("Read only!");
			return MOD_ERR;
		}

		/* over write  check */
		if(pnode->flag==1){
			printf("File is beening writen! \n");
			return OVERW_ERR;
		}

		/* write mode check */
		if(mode!=SEEK_CUR&&mode!=SEEK_SET&&mode!=SEEK_END){
			printf("ERROR:Unrecognizable write mode!\n");
			return MOD_ERR;
		}
		
		/* update inode of file */
		pnode->flag=1;	//set write flag
		pnode->f_length=len;
		pnode->f_blktotal=len/BLOCK_SIZE+1;
		  /* malloc block to write file */
		for(i=0;i<pnode->f_blktotal;i++){
			pblk=psp->freblkstart;
			freeblk=psp->free_blks[pblk].next_blknum;
			pnode->f_blknums[i]=freeblk;
			offset=BLOCK_SIZE*pblk;  //notice:don't care one a file in many block 
			fseek(fd,len,SEEK_SET);                
			fwrite((char *)buf,sizeof(struct dir),1,fd); 

		/* pass all check then write buferr to fd */
		}
		pnode->flag=0;	//set write flag
		return OK;
	}
	
	 unsigned int tread(struct inode * pnode,char * buf,  unsigned int len)
	{
		  unsigned int i,freeblk,pblk;
		  unsigned int offset,rwx;
		//struct inode * pn


		 /** read out super  block area at first **/
		if(psp==NULL){	//第一次进入则需读出 super block 结构
			psp=(struct super_block *)malloc(sizeof(struct super_block));
			if(psp==NULL){
				printf("Initiate global variable psp error! \n");
				return MAL_ERR;
			}
			/* read out super block */
			fread(psp,sizeof(struct super_block),1,fd);
		}
		/* user check */
		i=cur_usernum;
		if(pnode->i_uid!=psp->users[i].uid){
			printf("User illegal!");
			return PRI_ERR;	
		}

		/* file mode check */
		rwx=pnode->i_mode.rwx;
		if((rwx>>2)==0){
			printf(" Can't Read ! \n");
			return MOD_ERR;
		}

		/* read modle  check 
		if((mode!=SEEK_CUR)&&(mode!=SEEK_SET)&&(mode!=SEEK_END)){
			printf("ERROR:Unrecognizable write mode!\n");
			return MOD_ERR;
		} */
		
		/* update inode of file */
		pnode->flag=1;	//set write flag
		pnode->f_length=len;
		pnode->f_blktotal=len/BLOCK_SIZE+1;
		  /* malloc block to write file */
		for(i=0;i<pnode->f_blktotal;i++){
			pblk=psp->freblkstart;
			freeblk=psp->free_blks[pblk].next_blknum;
			pnode->f_blknums[i]=freeblk;
			offset=BLOCK_SIZE*pblk;  //notice:don't care one a file in many block 
			fseek(fd,len,SEEK_SET);                
			fread((char *)buf,sizeof(struct dir),1,fd); 
		}
		printf("\n Success!");
		return OK;
	}	


	/**********************************************
	 ** 函数入口:文件pnode指针
	 ** 函数出口:OK
	 ** 函数功能:关闭文件
	 **********************************************/
	 unsigned int tlose(struct inode * pnod)
	{
		//* 引用计数器应当减1
		pnod=NULL;
		return OK;
	}

	/**********************************************
	 ** 函数入口:待建目录名和父目录名
	 ** 函数出口:创建信息
	 ** 函数功能: 创建目录
	 **********************************************/
		
	 unsigned int tmkdir(const char * fdir,const char * dname)
	{
		
		 unsigned int i,j;
		  unsigned int nodnum ,next,rwx,num,recnum;
		 unsigned int offset;
		struct inode * pnode;
		struct inode  * newinode;
		struct dir * pdir;
	

		/** read out super  block area at first **/
		if(psp==NULL){	//第一次进入则需读出 super block 结构
			psp=(struct super_block *)malloc(sizeof(struct super_block));
			if(psp==NULL){
				printf("Initiate global variable psp error! \n");
				return MAL_ERR;
			}
			/* read out super block */
			fread(psp,sizeof(struct super_block),1,fd);
		}
		pnode=(struct inode *)malloc(sizeof(struct inode));
		if(pnode==NULL){
			printf("malloc error \n");
			return MAL_ERR;
		}

	/* begin systmily check 
	 * 1. disk space check
	 * 2. user priority check
	 * 3. operation mode check
	 * 4. max record limit check
	 * 5. name collision check
	 **/

	/* disk space check */
	if(psp->freblkstart==BLOCK_OUT){
		printf("Disk space isn't enough!\n");
		return SPANOELV_ERR;
	}
	/* Notice: getinode(fname) return inode index of file's dictionary  with name fname */
	/* possibility check */
	if((nodnum=getinode(fdir))<0){
		printf("Dictionary not exit!");
		return NOD_ERR;	
	}
	/* read out cordirate i_niode content from disk */
	offset=BLOCK_SIZE+nodnum*sizeof(struct inode);
	fseek(fd,offset,SEEK_SET);                
	fread((char *)pnode,sizeof(struct inode),1,fd);
	/* user priority check */
	i=cur_usernum;
	if(pnode->i_uid!=psp->users[i].uid){
		printf("Crea without priority!");
		return PRI_ERR;	
	}

	/* dir mode check */
	rwx=pnode->i_mode.rwx;
	if(((rwx<<1)>>2)==0){
		printf("Read only!");
		return MOD_ERR;
	}
	
	/*  dir name check */
		/* read out dir content from disk at first */
	for(i=0;i<pnode->f_blktotal;i++){ //notice: if dir file have more than two block ,here will make mistake 
 		pdir=(struct dir *)malloc(sizeof(struct dir));
		if(pdir==NULL){
			printf("malloc error \n");
			return MAL_ERR;
		}
		offset=BLOCK_SIZE*(pnode->f_blknums[i]);
		fseek(fd,offset,SEEK_SET);                
		fwrite((char *)pdir,sizeof(struct inode),1,fd);
		/* max file total limit check */
		if(pdir->rec_len>=MAX_RECTOTAL){
				printf("Error:the dictonary already full!\n");
				return RFULL_ERR;
		}
		/* check file name colicltion one by one */
		for(j=0;j<pdir->rec_len;j++)
			if(strcmp(pdir->rectables[j].rec_name,dname)==0){
				printf("Error:%s  already exit!\n",dname);
				return PATH_ERR;
			}
	}

	/* pass all check then creat new file      
	 * 1. modify father dictionary
	 * 2. rewrite dir file
	 * 3. rewrite its inode information
	 * 4. modify super_block free block information
     **/
				
		/* creat new inode of dir */
		newinode=(struct inode  * )malloc(sizeof(struct inode));
		if(newinode==NULL){
			printf("malloc new inode error!");
			return MAL_ERR;
		}
		/* malloc a free inode here */
		nodnum=psp->freenod_start;
		newinode->i_num=psp->free_inodes[nodnum].next_nodnum;
		/* update psp->freenod_start and psp->free_nods[] */
		next=psp->free_inodes[nodnum].next_nodnum;
		psp->free_inodes[nodnum].next_nodnum=psp->free_inodes[next].next_nodnum;
		psp->freenod_start=psp->free_inodes[next].next_nodnum; //freenod_start point to next free inode

		newinode->i_mode.rwx=6;
		newinode->i_mode.pri=1;
		newinode->i_mode.typ=1;
		num=cur_usernum;		
		newinode->i_uid=psp->users[num].uid;
		newinode->i_father=pnode->i_num;

		newinode->flag=0;	//no body is reading
		newinode->f_length=0;
		newinode->f_blktotal=0;
		newinode->f_blknums[0]=psp->freblkstart;		
		/* rewrite new inode to disk */
		offset=BLOCK_SIZE+sizeof(struct inode)*nodnum;
		fseek(fd,offset,SEEK_SET);                
		fwrite((char *)newinode,sizeof(struct inode),1,fd);

		/* update its dictionary file */		
		recnum=pdir->rec_len;
		/* if dictionary file is empty at begining */
		if(recnum==0){		//deal if new file is the first file in the dictinary Notice:how to intiate rec_len =0 ?
			pdir->rectables[0].flag=1;
			strcpy(pdir->rectables[0].rec_name,dname);
			pdir->rectables[0].rec_idnum=psp->freenod_start; //save inode of currrent dir
			/* now initate all below flag to zear in this dictinary */
			for(i=1;i<MAX_RECTOTAL;i++)
				pdir->rectables[i].flag=0;
			pdir->rec_len=1;
		}
		/* if dictionary file isn't empty at begining */
		else{
			for(i=1;i<MAX_RECTOTAL;i++)		//search free record space */
				if(pdir->rectables[i].flag==0)
					break;			
			if(i==MAX_RECTOTAL){
				printf("NO RECORD SPACE! \n");
				return RFULL_ERR;
			}
			pdir->rectables[i].flag=1;
			strcpy(pdir->rectables[i].rec_name,dname);
			pdir->rectables[i].rec_idnum=psp->freenod_start; //save inode of currrent file
			pdir->rec_len++;
		}

		/* rewrite dir file */
		for(i=1;i<=pnode->f_blktotal;i++){
			 unsigned int blknum=pnode->f_blknums[i];
			offset=BLOCK_SIZE*blknum;
			fseek(fd,offset,SEEK_SET);                
			fwrite((char *)pdir+(i-1)*sizeof(struct dir),sizeof(struct dir),1,fd); 
		}
		printf("\n Success!");
		return OK;
	}


	/**********************************************
	 ** 函数入口:文件pnode指针
	 ** 函数出口:OK
	 ** 函数功能:关闭文件
	 **********************************************/
	 unsigned int trmdir(const char * fdir,const char * dname)
	{
						
		 unsigned int i,j,idnum,offset;
		 unsigned int nodnum,rwx,fnum,temnod;
		 unsigned int blknum,temblk,blklen;
		struct inode * pnode,* ptemnod,* subpnd,*pnd;
		struct dir * pdir,* pbasedir;


		/** read out super  block area at first **/
		if(psp==NULL){	//第一次进入则需读出 super block 结构
			psp=(struct super_block *)malloc(sizeof(struct super_block));
			if(psp==NULL){
				printf("Initiate global variable psp error! \n");
				return MAL_ERR;
			}
			/* read out super block */
			fread(psp,sizeof(struct super_block),1,fd);
		}
		pnode=(struct inode *)malloc(sizeof(struct inode));
		if(pnode==NULL){
			printf("malloc error \n");
			return MAL_ERR;
		}

		/* Notice: getinode(fname) return inode index of file's dictionary  with name fname */
		/* possibility check */
		if((nodnum=getinode(fdir))<0){
			printf("Dictionary not exit!");
			return NOD_ERR;	
		}

		/* read out cordirate i_niode content from disk */
		offset=BLOCK_SIZE+nodnum*sizeof(struct inode);
		fseek(fd,offset,SEEK_SET);                
		fread((char *)(char *)pnode,sizeof(struct inode),1,fd);
		/* user priority check */
		i=cur_usernum;
		if(pnode->i_uid!=psp->users[i].uid){
			printf("User without priority!");
			return PRI_ERR;		
		}

		/*  dir mode check */
		rwx=pnode->i_mode.rwx;
		if(((rwx<<1)>>2)==0){
			printf("No write promission !");
			return MOD_ERR;
		}
			
		/* update the dictionary of the file to delet according inode 
		 * 1. read out the dictionary of the file
		 * 2. search the record number of the file 
		 * 3. update the dictionary record
		 */
		pnd=(struct inode *)malloc(sizeof(struct inode));
		if(pnd==NULL){
			printf("Malloc inode struct error!\n");
			return MAL_ERR;
		}
		 fnum=pnode->i_num;
		 offset=BLOCK_SIZE+sizeof(struct inode)*fnum;
		/* read out dictionary inode */
		fseek(fd,offset,SEEK_SET);                
		fread((char *)pnd,sizeof(struct inode),1,fd); 
		/* read out dictionary content from disk to dir struct */
		pdir=(struct dir *)malloc(sizeof(struct dir));
		if(pdir==NULL){
			printf("Malloc dir struct error!\n");
			return MAL_ERR;
		}
		blklen=pnd->f_blktotal;
		for(i=0;i<blklen;i++){
			blknum=pnd->f_blknums[i];
			offset=BLOCK_SIZE*(blknum+1);
			/* read out dictionary dir content to a dir struct point*/
			fseek(fd,offset,SEEK_SET);                
			fread((char *)pdir+offset-BLOCK_SIZE,sizeof(struct dir),1,fd); 
		}

		/* now update the dictionary of the dir
		 * 1. search the rectables to find dir's record position 
		 * 2. free block area of all records in the dir 		  
		 * 3. uopdate this dir's father dictionary
		 * 4. free all used i-node area
		 **/
		
		//  search the rectables to find dir's record position 
		for(j=0,i=0;(i<MAX_RECTOTAL)&&(j<pdir->rec_len);i++){
			if(pdir->rectables[i].flag==0)
				continue;
			else {  j++;
					if((strcmp(pdir->rectables[i].rec_name,dname))==0)
						break;
				 }
		}
		if(i== MAX_RECTOTAL||j==pdir->rec_len){
			printf("Dir %s not exit! \n",dname);
			return  NOF_ERR;

⌨️ 快捷键说明

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