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

📄 fs.c

📁 模拟linux操作系统文件系统资源管理的C程序
💻 C
📖 第 1 页 / 共 4 页
字号:

		if(ch!='/'){
			printf("Path error! \n");
			return PATH_ERR;
		}
		i++;
		leng=strlen(rname);
		while(ch!=' '){
			 ch=*(rname+i++);
			 if(ch!='/')
				buf[j++]=ch;
			 else { /* get sub dir name from file and path name*/
					for(k=0;k<j;k++)
						*(subname+k)=buf[k];
					j=0;							// resolve sub dir name
					/* open boot dir file and check one by one,return the inodenum of the file
					 * . read out inode conten from disk by nodnum
					 * . read out dir content pointed by nodnum
					 * . find the inode number of subdir */

					 /* read out itself inode */
					offset=BLOCK_SIZE+sizeof(struct inode)*nodnum;
					fseek(fd,offset,SEEK_SET);                
					fread((char *)pnode,sizeof(struct inode),1,fd); 
					/* read out dictionary content from disk to dir struct */
					blklen=pnode->f_blktotal;
					for(i=0;i<blklen;i++){
						blknum=pnode->f_blknums[i];
						offset=BLOCK_SIZE*blknum;
						/* read out dictionary dir content to a dir struct point*/
						fseek(fd,offset,SEEK_SET);                
						fread((char *)pdir,sizeof(struct dir),blklen,fd); 
					}
					for(i=0;i<pdir->rec_len;i++){
						if(strcmp(subname,pdir->rectables[i].rec_name)!=0)
							continue;
						else break;
					}
					if(i==pdir->rec_len){
						printf("Path error!");
						return PATH_ERR;
					}
					nodnum=pdir->rectables[i].rec_idnum;
			 }
		}
		printf("\n Success!");
		return nodnum;
	}


/****************************************************
 * 入口参数:代创建文件目录和名称
 * 出口参数:错误代码或完成信息
 * 实现过程:
 ****************************************************/

 unsigned int tcreat(const char * dir,const char * fname)
{
	  unsigned int i,j,num;
	 unsigned int nodnum,next,recnum,blknum;
	 unsigned int offset;
	struct inode * pnode ,* 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 */
	/* psp->freblkstart==0 might not idicate space full in detail */
	if(psp->freblkstart==BLOCK_OUT){ 
		printf("Disk space isn't enough!\n");
		return SPANOELV_ERR;
	}
	/* Notice: getinode(fname) return inode index of the dictionary of fname */
	/* possibility check */
	if((nodnum=getinode(dir))<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("Creat without priority!");
		return PRI_ERR;	
	}

	/* file mode check */
	if((pnode->i_mode.rwx==4)||(pnode->i_mode.rwx==5)){
		printf("Read only!");
		return MOD_ERR;
	}
	
	/*  file name check */
	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);                
		fread((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,fname)==0){
				printf("Error:%s  already exit!\n",fname);
				return PATH_ERR;
	}

	/* pass all check then creat new file 
     * 1. malloc block area
	 * 2. modify father dictionary
	 * 3. rewrite dir file
	 * 4. rewrite its inode information
	 * 5. modify super_block free block information
     **/
			
	//	rec_name[pdir->rec_len]=fname; 
		/* creat new inode of file*/
		
		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=(cur_usernum==0)?0: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_ken =0 ?
			pdir->rectables[0].flag=1;
			strcpy(pdir->rectables[0].rec_name,fname);
			pdir->rectables[0].rec_idnum=psp->freenod_start; //save inode of currrent file
			/* 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,fname);
			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++){
			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;
	
}
	/***************************************
	 * 入口参数:文件的名称
	 * 出口参数:文件对应的inode指针
	 * 函数功能:根据文件名,逐级检索目录文
	 *           件,找到他的inode 指针
	 ***************************************/	 
	struct inode * topen (const char * fname)
	{
		 unsigned int offset,nodnum;
		struct inode * pnode;
		


			/** 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);
		}
		/*	Notice: getinode(fname) return inode index of file with name fname */
		/* possibility check */
		if((nodnum=getinode(fname))<0){
			printf("Dictionary not exit!");
		//	return NOD_ERR;	
		}
		
		pnode=(struct inode  * )malloc(sizeof(struct inode));
		if(pnode==NULL){
			printf("malloc new inode error!");
			//return MAL_ERR;
		}
		/* read out cordirate i_niode content */
		offset=BLOCK_SIZE+nodnum*sizeof(struct inode);
		fseek(fd,offset,SEEK_SET);                
		fread((char *)pnode,sizeof(struct inode),1,fd);	
		printf("\n Success!");	
		return pnode;
	}
	
	
	/***************************************
	 * 入口参数:文件的名称
	 * 出口参数:文件对应的inode指针
	 * 函数功能:根据文件名,逐级检索目录文
	 *           件,找到他的inode 指针
	 ***************************************/	 
	 unsigned int tclose (struct inode * pnod)
	{
		 unsigned int offset;
		
		pnod->flag=0;
		
		/* rewrite new inode to disk */
		offset=BLOCK_SIZE+sizeof(struct inode)*pnod->i_num;
		fseek(fd,offset,SEEK_SET);                
		fwrite((char *)(char *)pnod,sizeof(struct inode),1,fd);

		printf("\n Success!");
		return OK;
	}
	
	/***************************************
	 * 入口参数:文件的inode指针
	 * 出口参数:返回信息
	 * 函数功能:删除inode所指向的文件,且
	 *           相应地修改目录,回收磁盘块
	 ***************************************/
	 unsigned int tdelet(struct inode * pnode)
	{
		 unsigned int i,j,fnum,offset,blklen;
		 unsigned int nodnum,temnod;
		 unsigned int blknum,temblk;
		struct inode * pnd;
		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);
		}

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

		/* delet file mode check */
		if((pnode->i_mode.rwx==5)||(pnode->i_mode.rwx==4)){
			printf("Read only!");
			return MOD_ERR;
		}
		
		/* update sup_block  struct */
		for(i=1;i<(pnode->f_blktotal);i++){
			blknum=pnode->f_blknums[i];
			temblk=psp->freblkstart;
			psp->free_blks[blknum].next_blknum=psp->free_blks[temblk].next_blknum;
			psp->free_blks[temblk].next_blknum=psp->free_blks[blknum].next_blknum;
		}

		/* 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_father;
		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 *)(char *)pdir,sizeof(struct dir),1,fd); 
		}

		/* now update the dictionary of the file 
		 * 1. search the rectables to find file's record position 
		 * 2. update filetable struct of the position
		 */
		for(j=0,i=0;(i<MAX_RECTOTAL)&&(j<pdir->rec_len);i++){
			if(pdir->rectables[i].flag==0)
				continue;
			else { j++;
				  if(pdir->rectables[i].rec_idnum == pnode->i_num)
					break;
				  else continue;
				}
		}
		if(i== MAX_RECTOTAL||j==pdir->rec_len){
			printf("File not exit! \n");
			return  NOF_ERR;
		}
		pdir->rectables[i].flag=0;
		/* now rewrite dir file content to its disk */
		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);                
			fwrite((char *)(char *)pdir,sizeof(struct dir),1,fd); 
		}

		/*  free the inode of file to delet */
		/* update psp->free_nod[] */
			/* update sup_block  struct */
		
		for(i=0;i<pdir->rec_len;i++){
			nodnum=pdir->rectables[i].rec_idnum;
			temnod=psp->freenod_start;
			psp->free_inodes[blknum].next_nodnum=psp->free_inodes[temnod].next_nodnum;
			psp->free_inodes[temnod].next_nodnum=psp->free_inodes[nodnum].next_nodnum;
		}
		printf("\n Success!");
		return OK;
	}


	/*********************************************

⌨️ 快捷键说明

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