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

📄 fcb.cpp

📁 在Linux Red Hat下用C++设计并实现一个多用户多级目录结构的文件系统。
💻 CPP
字号:
#include"fcb.h"
#include<string.h>
#include<iostream.h>

ifcb::ifcb()
{
//初始化curfp,iadd[],fcbnum
	curfp=NULL;
	for(int i=0;i<fcbmax;i++)
	{
		fcbi[i]=NULL;
	}
	for(int k=0;k<256;k++)
	{
		iadd[k]=0;
	}
	fcbnum=0;
}

ifcb::~ifcb()
{
//存储iadd[]以及fcbi[]中的信息
	if(curfp!=NULL)
		putiadd(curfp);
	for(int f=0;f<16;f++)
	{
		if(fcbi[f]!=NULL)
			iput(fcbi[f]);
	}
}

int ifcb::getiadd(fcb *fp)
{
//读出指定fcb的一级间接寻址的信息
	if(fp==NULL)
		return OK;
	if(fp->f_add[8]==0)
	{
		for(int i=0;i<256;i++)
		{
			iadd[i]=0;
		}
		return OK;
	}
	else
	{
		char buf[bsize+1];
		if(iblock.bread(fp->f_add[8],buf)==BLKREADERR)
		{
			cout<<"GET IADD ERROR\n";
			return BLKREADERR;
		}
		for(int num=0;num<256;num++)
		{
			iadd[num]=int((unsigned char)buf[num*2])*256+int((unsigned char)buf[num*2+1]);
		}
		return OK;
	}
}

int ifcb::putiadd(fcb *fp)
{
//存储iadd[]中的内容
	if(fp==NULL)
		return OK;
	if(fp->f_add[8]==0)
		return OK;
	else
	{
		char buf[bsize+1];
		for(int num=0;num<256;num++)
		{
			buf[num*2]=char(iadd[num]/256);
			buf[num*2+1]=char(iadd[num]%256);
		}
		buf[512]='\0';
		if(iblock.bwrite(fp->f_add[8],buf)==BLKWRITEERR)
		{
			cout<<"PUT IADD ERROR\n";
			return BLKWRITEERR;
		}
		return OK;
	}
}

int ifcb::addblock(fcb *fp,int pblock)
{
//增加空闲块到指定的FCB的空间里
	int i=0;
	for(;i<263;i++)
	{
		if(getblock(fp,i)==0)
			break;
	}
	if(i>=263)
	{
		cout<<"ADD BLOCK ERROR\n";
		return ERROR;
	}
	if(i<8)
	{
		fp->f_add[i]=pblock;
		return OK;
	}
	else
	{
		if(i==8)
		{
			char buf[bsize+1];
			for(int j=0;j<512;j++)
			{
				buf[j]=(char)0;
			}
			buf[512]='\0';
			buf[0]=char(pblock/256);
			buf[1]=char(pblock%256);
			int blkno=iblock.balloc();
			if(blkno==NOSPACE||blkno==BLOCKERR)
			{
				cout<<"ADD BLOCK ERROR\n";
				return blkno;
			}
			if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
			{
				cout<<"ADD BLOCK ERROR\n";
				return BLKWRITEERR;
			}
			fp->f_add[8]=blkno;
			iadd[0]=pblock;
			for(int t=1;t<256;t++)
			{ 
				iadd[t]=0;
			}
			curfp=fp;
			return OK;
		}
		else
		{
			if(i>8)
			{  
				iadd[i-8]=pblock;
				return OK;
			}
		}
	}
}

int ifcb::getblock(fcb *fp,int lblock)
{
//得到指定FCB空间的指定逻辑块对应的物理块
	if(lblock<8&&lblock>=0)
		return fp->f_add[lblock];
	else
	{
		if(lblock>=8)
		{
			if(fp->f_add[8]==0)
				return 0;
			else
			{
				if(fp!=curfp)
				{
					if(curfp!=NULL)
						putiadd(curfp);
					getiadd(fp);
					curfp=fp;
				}
				return iadd[lblock-8];
			} 
		}
	}
}

int ifcb::readi(fcb *fp,int offset,int count,char*base)
{
//读指定文件的信息
	if(offset/bsize<0||offset/bsize>=263||offset>fp->f_fsize-1)
	{
		cout<<"FCB READ ERROR\n";
		return FCBREADERR;
	}
	int temp=0;
	char buf[bsize+1];
	int num;
	if((fp->f_fsize-(offset+1)+1)>count)
		num=count;
	else
		num=fp->f_fsize-(offset+1)+1;
	for(int i=0;;i++)
	{
		if(iblock.bread(getblock(fp,(offset/bsize)+i),buf)==BLKREADERR)
		{
			cout<<"BLOCK READ ERROR\n";
			return BLKREADERR;
		}
		if(i==0)
			temp=0;
		else
			if(i==1)
				temp=bsize-offset%bsize;
			else
				temp=bsize-offset%bsize+bsize*(i-1);
		if(num-(bsize-offset%bsize)>=0&&i==0)
		{
			for(int k=0;k<(bsize-offset%bsize);k++)
				base[k]=buf[offset%bsize+k];
			base[bsize-offset%bsize]='\0';
		}
		else
		{
			if((num-(bsize-offset%bsize)-i*bsize)<0)
			{
				for(int j=temp;j<num;j++)
				{
					if(i==0)
						base[j]=buf[j-temp+offset%bsize];
					else
						base[j]=buf[j-temp];
             
				}
				base[num]='\0';
				fp->f_count++;
				return num;
			}
			else
				strcat(base,buf);
		}
   }
}

int ifcb::writei(fcb *fp,int offset,int count,char*base)
{
	if(offset>fp->f_fsize||offset<0)
	{
		cout<<"FCB WRITE ERROR\n";
		return FCBWRITEERR;
	}
	if((offset+count-1)/bsize>=263)
	{
		cout<<"NOT ENOUGH SPACE\n";
		return NOSPACE;
	}   
 //写信息入指定的文件
	int temp=0;
	char buf[bsize+1];
	int ph=-1;
	int blkno;
	for(int i=0;;i++)
	{
		if(i==0)
			temp=0;
		else
			if(i==1)
				temp=bsize-offset%bsize;
			else
				temp=bsize-offset%bsize+bsize*(i-1);
		if(ph==0)
		{
			blkno=iblock.balloc();
			if(blkno==NOSPACE||blkno==BLOCKERR)
			{
				cout<<"FCB WRITE ERROR\n";
				return blkno;
			}
			addblock(fp,blkno);
		}
		else
		{
			ph=getblock(fp,offset/bsize+i);
			if(ph==0)
			{
				blkno=iblock.balloc();
				if(blkno==NOSPACE||blkno==BLOCKERR)
				{
					cout<<"FCB WRITE ERROR\n";
					return blkno;
				}
				addblock(fp,blkno);
			}
			else
			{
				blkno=ph;
				if(i==0)
				{
					if(iblock.bread(blkno,buf)==BLKREADERR)
					{
						cout<<"FCB WRITE ERROR\n";
						return BLKREADERR;
					}
				}
			}
		}
		if(count-(bsize-offset%bsize)>0&&i==0)
		{
			for(int k=0;k<(bsize-offset%bsize);k++)
				buf[offset%bsize+k]=base[k];
			if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
			{
				cout<<"FCB WRITE ERROR\n";
				return BLKWRITEERR;
			}
		}
		else
		{
			if((count-(bsize-offset%bsize)-i*bsize)<=0)
			{                                                                  
				for(int j=temp;j<count;j++)
				{
					if(i==0)
						buf[offset%bsize+j-temp]=base[j];
					else
						buf[j-temp]=base[j];                                                                             
				}
				if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
				{
					cout<<"FCB WRITE ERROR\n";
					return BLKWRITEERR;
				}
				if((offset+count-1)/bsize<(fp->f_fsize-1)/bsize)
				{
					for(int tt=((offset+count-1)/bsize)+1;tt<=(fp->f_fsize-1)/bsize;tt++)
					{
						iblock.brelse(getblock(fp,tt));
					}
				}    
				fp->f_fsize=offset+count;
				if(fp->f_flag<FCHG)
					fp->f_flag=fp->f_flag|FCHG;
				fp->f_count++;
				return count;
			}
			else
			{
				for(int t=temp;t<temp+bsize;t++)
				{
					buf[t-temp]=base[t];
				}
				if(iblock.bwrite(blkno,buf)==BLKWRITEERR)
				{
					cout<<"FCB WRITE ERROR\n";
					return BLKWRITEERR;
				}
			}
		}
	}
}
   
fcb *ifcb::iget(int blkno,int num)
{
//读出指定的文件目录结构的信息,并产生对应的FCB结构
	int free=0;
	for(;free<16;free++) //寻找FCB系统中空闲的位置
	{
		if(fcbi[free]==NULL)
        break;
	}
	if(free>=16)
	{
		cout<<"FCB STRUCT IS FULL\n";
		return NULL;
	}
	char buf[bsize+1];
	if(iblock.bread(blkno,buf)==BLKREADERR)
	{
		cout<<"CREATE FCB ERROR\n";
		return NULL;
	}
	fcbi[free]=new struct fcb;//产生fcb结构并初始化
	fcbi[free]->f_mode=int((unsigned char)buf[num*dsize])*256+int((unsigned char)buf[num*dsize+1]);
	fcbi[free]->f_uid=buf[num*dsize+2];
	fcbi[free]->f_gid=buf[num*dsize+3];
	fcbi[free]->f_fsize=int((unsigned char)buf[num*dsize+4])*16777216+int((unsigned char)buf[num*dsize+5])*65537+int((unsigned char)buf[num*dsize+6])*256+int((unsigned char)buf[num*dsize+7]);
	for(int n=0;n<8;n++)
	{
		fcbi[free]->f_name[n]=buf[num*dsize+8+n];
	}
	for(int a=0;a<8;a++)
	{
		fcbi[free]->f_add[a]=int((unsigned char)buf[num*dsize+16+a*2])*256+int((unsigned char)buf[num*dsize+16+a*2+1]);
	}
	fcbi[free]->f_blkno=blkno;
	fcbi[free]->f_number=num;
	fcbi[free]->f_count=1;
	fcbi[free]->f_flag=FLOCK;
	fcbnum++;
	return fcbi[free];
}

int ifcb::iput(fcb *fp)
{
	if(fp->f_flag>=FCHG) //fcb结构信息有改变,则存储该fcb的信息到文件目录结构中
	{
		char buf[bsize+1];
		if(iblock.bread(fp->f_blkno,buf)==BLKREADERR)
		{
			cout<<"SAVE FCB ERROR\n";
			return BLKREADERR;
		}
		buf[fp->f_number*dsize]=char(fp->f_mode/256);
		buf[fp->f_number*dsize+1]=char(fp->f_mode%256);
		buf[fp->f_number*dsize+2]=fp->f_uid;
		buf[fp->f_number*dsize+3]=fp->f_gid;
		buf[fp->f_number*dsize+4]=char(fp->f_fsize/16777216);
		buf[fp->f_number*dsize+5]=char((fp->f_fsize%16777216)/65536);
		buf[fp->f_number*dsize+6]=char(((fp->f_fsize%16777216)%65536)/256);
		buf[fp->f_number*dsize+7]=char(((fp->f_fsize%16777216)%65536)%256);
		for(int n=0;n<8;n++)
		{
			buf[fp->f_number*dsize+8+n]=fp->f_name[n];
		}
		for(int a=0;a<8;a++)
		{
			buf[fp->f_number*dsize+16+a*2]=char(fp->f_add[a]/256);
			buf[fp->f_number*dsize+16+a*2+1]=char(fp->f_add[a]%256);
		}
		if(iblock.bwrite(fp->f_blkno,buf)==BLKWRITEERR)
		{
			cout<<"SAVE FCB ERROR\n";
			return BLKWRITEERR;
		}
	}
//删除FCB系统中对应的fcb
	for(int w=0;w<16;w++)
	{
		if(fp==fcbi[w])
		{
			fcbi[w]=NULL;
			delete fp;
			break;
		}
	}
	fcbnum--;
	return OK;
}

fcb *ifcb::namei(fcb *fp,char*name,int f_mode)
{
//在FCB系统中查找,fp==NULL是查找根目录
	for(int it=0;it<fcbmax;it++)
	{
		if(fcbi[it]!=NULL)
		{
			if(strcmp(fcbi[it]->f_name,name)==0)
			{
				if(fp==NULL&&fcbi[it]->f_blkno==0)
					return fcbi[it];
				int u;
				for(int yy=0;yy<263;yy++)
				{
					u=getblock(fp,yy);
					if(u==0)
						break;
					else
					{
						if(u==fcbi[it]->f_blkno)
						{  
							if((fcbi[it]->f_mode==IFDIR&&f_mode==IFDIR)||(fcbi[it]->f_mode>=IFREG&&f_mode>=IFREG))
								return fcbi[it];
						}
					}
                 
				}
			}
		}
	}
//在指定的FCB对应的空间中查找
	char buf[bsize+1];
	char f_name[8];
	int d_mode;
	if(fp==NULL)
	{
		iblock.bread(0,buf);
		for(int g=0;g<8;g++)
		{
			f_name[g]=buf[dsize*15+8+g];
		}
		d_mode=int((unsigned char)buf[dsize*15])*256+int((unsigned char)buf[dsize*15+1]);
		if(strcmp(name,f_name)==0)
		{
			if((d_mode==IFDIR&&f_mode==IFDIR)||(d_mode>=IFREG&&f_mode>=IFREG))
				return iget(0,15);
		}
		return NULL;
	}
	int blkno;
	int blkend;
	int dirend;
	blkend=(fp->f_fsize-1)/bsize;
	dirend=((fp->f_fsize-1)%bsize)/dsize;
	for(int i=0;i<263;i++)
	{
		if(i==(blkend+1))
			return NULL;
		blkno=getblock(fp,i);
		if(blkno==0)
			return NULL;
		if(iblock.bread(blkno,buf)==BLKREADERR)
			return NULL;
		for(int d=0;d<16;d++)
		{
			if(i==blkend&&d==(dirend+1))
				return NULL;
			for(int n=0;n<8;n++)
			{
				f_name[n]=buf[dsize*d+8+n];
			}
			d_mode=int((unsigned char)buf[dsize*d])*256+int((unsigned char)buf[dsize*d+1]);
			if(strcmp(f_name,name)==0)
			{
				if((d_mode==IFDIR&&f_mode==IFDIR)||(d_mode>=IFREG&&f_mode>=IFREG))
					return iget(blkno,d);
			}
		}
	}
	return NULL;
}

fcb *ifcb::icreate(fcb *fp,char*name)
{
//在指定的fcb下创建fcb,fp==NULL,是创建根目录
	int i=0;
	for(;i<fcbmax;i++)
	{
		if(fcbi[i]==NULL)
			break;
	}
	if(i>=fcbmax)
		return NULL;
	fcb *ft=new struct fcb;
	int blkno;
	int num;
	if(fp==NULL)
	{
		blkno=0;
		num=15;
		ft->f_uid='0';
		ft->f_gid='0';
	}
	else
	{
		if(fp->f_fsize==0||(fp->f_fsize-1)%bsize==511)
		{
			blkno=iblock.balloc();
			addblock(fp,blkno);
			num=0;
		}
		else
		{
			blkno=getblock(fp,(fp->f_fsize-1)/bsize);
			num=(((fp->f_fsize-1)%bsize)/dsize)+1;
		}
		fp->f_fsize=fp->f_fsize+32;
		fp->f_flag=FUPD|FCHG;
	}
	ft->f_count=1;
    ft->f_flag=FCHG;
    ft->f_blkno=blkno;
    ft->f_number=num;
    ft->f_mode=IFMT;
    ft->f_fsize=0;
    strcpy(ft->f_name,name);
    for(int a=0;a<8;a++)
    {
       ft->f_add[a]=0;
    }
    fcbi[i]=ft;
    fcbnum++;
    return ft;
}
  
int ifcb::idelete(fcb *pfp,fcb *fp)
{
//删除父目录中,该文件目录的信息
	for(int yy=0;yy<263;yy++)
	{
		if(getblock(pfp,yy)==fp->f_blkno)
		{
			char*base;
			if(yy*bsize+fp->f_number*dsize+32>pfp->f_fsize-1)
			{
				base=new char[pfp->f_fsize-32+1];
				readi(pfp,0,pfp->f_fsize-32,base);
				writei(pfp,0,pfp->f_fsize-32,base);
			}
			else
			{
				base=new char[pfp->f_fsize-1-(yy*bsize+fp->f_number*dsize+32)+1+1];
				readi(pfp,yy*bsize+fp->f_number*dsize+32,pfp->f_fsize-1-(yy*bsize+fp->f_number*dsize+32)+1,base);
				writei(pfp,yy*bsize+fp->f_number*dsize,pfp->f_fsize-1-(yy*bsize+fp->f_number*dsize+32)+1,base);        
			}
			if(pfp->f_flag<FCHG)
				pfp->f_flag=pfp->f_flag|FCHG;
			delete[]base;
			break;
		}
	}
//删除该FCB对应的文件,释放空间
	int g;     
	for(int kk=0;kk<263;kk++)
	{
		g=getblock(fp,kk);
		if(g==0)
			break;
		else
			iblock.brelse(g);
	}
	if(curfp==fp)
		curfp=NULL;
	for(int ee=0;ee<fcbmax;ee++)
	{
		if(fcbi[ee]==fp)
		{
			fcbi[ee]=NULL;
			fcbnum--;
			delete fp;
		}
	}
	return OK;
}

⌨️ 快捷键说明

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