文件系统的模拟和实现

实验4 文件系统的模拟和实现@操作系统

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BLOCKSIZ 512	/*磁盘块大小 */
#define NICFREE 10      /*每组的块数 */
#define FILEBLK 25 	/*文件区磁盘块总数 */
#define K 11 	        /*文件区开始块 */
struct filsys           /*超级块部分数据结构 */
{  unsigned int s_nfree;	/*空闲盘块数 */
   unsigned short s_pfree;      /*空闲盘块号栈指针 */
   unsigned int s_free[NICFREE];/*空闲盘块号栈 */
};


struct filsys filsys;		// 超级块数据结构  
FILE *fd;
char input_buf[20];             //命令行输入缓冲区
int over;			//命令行结束标记


unsigned int balloc()
{	
	unsigned int block_buf0[BLOCKSIZ];
	unsigned int free_block, free_block_num;
	int i;
	if(filsys.s_nfree == 0)	                    // 磁盘已满,无空闲盘块  
	{
	printf( "Disk has no space\n" );
	return -1;
	}
	printf("balloc=%d\n",filsys.s_pfree);
	free_block = filsys.s_free[filsys.s_pfree];		// 取得当前空闲盘块号 
	if(filsys.s_pfree == 0)			            // 已经是栈底  
	{	
        bread(filsys.s_free[0],block_buf0);        // 调用bread读取栈底盘块号所对应的盘块数据到block_buf0中
        free_block_num=block_buf0[NICFREE];
		for(i=0;i<=block_buf0[NICFREE];i++){
				filsys.s_free[i]=block_buf0[i];
		}                                          //从block_buf0 读取该空闲盘块组的盘块数  
	                                              // 把盘块号组block_buf0数据写入到空闲盘块号栈中
        filsys.s_pfree = free_block_num - 1;	  // 指针指向栈顶  	
	}
	else
		filsys.s_pfree--;			// 栈指针下移一位  
	filsys.s_nfree--;               // 空闲盘块数减1 
	return free_block;				// 返回空闲盘块号 
}

// 空闲盘块回收函数:bfree
void bfree( unsigned int block_num )
{	int i;
	unsigned int block_buf0[BLOCKSIZ];
	if ( ( block_num<=0) || ( block_num>FILEBLK) )
	{     printf("bfree: error block_num\n");
   	   return ;
	}
	filsys.s_pfree++;		   	               // 栈指针上移一位  
	if( filsys.s_pfree == NICFREE )	    	   // 空闲盘块栈已满  
	{	
		block_buf0[NICFREE] = NICFREE;	       // 空闲盘块栈的盘块数NICFREE记入缓冲区  
        for(i=0;i<block_buf0[NICFREE];i++){
		 filsys.s_free[i]=block_buf0[i];// 把空闲盘块中数据读入缓冲区block_buf0
		}                                  
		filsys.s_pfree = 0;			           // 栈指针指向栈底  
		bwrite(block_num,block_buf0);          // 调用bwrite将缓冲区block_buf0内容写入新回收的盘块中 
	}
	filsys.s_free[filsys.s_pfree] = block_num;	// 回收盘块号 
	filsys.s_nfree++;				           // 空闲盘块加1  
}


// 将buf数据写入盘块号为ino的盘块中
void bwrite( unsigned int ino, unsigned int *  buf )
{  fseek( fd, BLOCKSIZ * ino, SEEK_SET );
   fwrite( buf, 1, BLOCKSIZ, fd );}

// 从盘块号为ino的盘块中读取数据到buf:
void bread( unsigned int ino, unsigned int *  buf )
{   fseek( fd,  BLOCKSIZ * ino, SEEK_SET );
    fread( buf, 1, BLOCKSIZ, fd );}

void display()
{  unsigned int block_buf0[BLOCKSIZ / sizeof( int )];
   //显示filsys.s_nfree、filsys.s_pfree、filsys.s_free[filsys.s_pfree];
   printf("filsys.s_nfree:%d\n",filsys.s_nfree);
   printf("filsys.s_pfree:%d\n",filsys.s_pfree);
   printf("current free:%d#\n",filsys.s_free[filsys.s_pfree]);
   int i=0;
   while ( i<=filsys.s_pfree && filsys.s_nfree>0)
   {    printf("filsys.s_free[%d]=%d \n",i,filsys.s_free[i] );
         i++;
   };
   int lastBlk=filsys.s_free[0];
   int free_block_num=NICFREE;
   while ( lastBlk>0 )
   {   bread( lastBlk, block_buf0 );
        free_block_num = block_buf0[NICFREE];
       //显示lastBlk和free_block_num 变量值;
       printf("lastBlk:%d#\n",lastBlk);
       printf("free_block_num:%d\n",free_block_num);
        for( i=0; i <free_block_num ; i++ )
        {   printf("block_buf0[%d]=%d \n",i,block_buf0[i] );}
        lastBlk=block_buf0[0];
    }  
}

void getcmd()
{  int i=0;
    while( !over )
    {   input_buf[i] = getchar();
        if( input_buf[i] == ' ' )
        {	if( i == 0 )	// 命令行的开始是空格,应舍去  
	    i--;
	else
	{   input_buf[i]='\0';
	     break;}
        }else
	if( input_buf[i] == '\n' )
	{   over = 1;
	    input_buf[i]='\0';
	    break;
	}
        i++;
     }
}

int cmdexp()
{   char buf[5];
    unsigned int d;
     over = 0;
     printf( "[@localhost]# "); // 显示命令提示行
     getcmd(); // 读取用户输入命令
     if(( strcmp( input_buf, "df" ) == 0 ))
     {	display(); //显示
	return 0;
      }
     if(( strcmp( input_buf, "alloc" ) == 0 ))
     {	balloc(); //分配
	return 0;
      }
     if(( strcmp( input_buf, "bfree" ) == 0 ))
     {  
        scanf("%d",&d);
        bfree(d); //回收
	return 0;
      }


      if( strcmp( input_buf, "exit" ) == 0 )
       {
        printf( "%s: \n", "exit" );
 	return 1;
       }
       if( input_buf[0] != '\0' ) // 找不到该命令 
       {  printf( "%s: command not found\n", input_buf );
       }
       return 0;
}



int main()
{
unsigned int block_buf1[BLOCKSIZ];
fd = tmpfile();  
char* buf = (char * )malloc((FILEBLK+K)*BLOCKSIZ );// 申请空间 
fseek( fd, 0, SEEK_SET );
fwrite( buf, 1, (FILEBLK+K)*BLOCKSIZ , fd );
free(buf);

filsys.s_nfree = FILEBLK ; // 空闲文件块数  
// 把第1组空闲盘块写入空闲盘块号栈  
int i=0;
for( i = 0; i < NICFREE; i++ )
{    filsys.s_free[i] = NICFREE - i + K - 1;
}
filsys.s_pfree = NICFREE - 1;	// 当前空闲盘块号栈指针  

int j=0;
for( i = NICFREE * 2 - 1; i < FILEBLK; i += NICFREE )
{  for( j = 0; j < NICFREE; j++ )
    {  block_buf1[j] = i - j + K;  //写下一组盘块空闲块号
     }  
    block_buf1[NICFREE] = NICFREE;  //记录本组的空闲盘块数  
    //把缓冲区内容写到每组空闲盘块号的最后一块中  
    bwrite( i - NICFREE + K, block_buf1 );
}

// 最后一组空闲盘块数可能不足NICFREE块,故需单独处理  
i = i - NICFREE;
block_buf1[0] = 0;
for( j = 1; j < FILEBLK - i; j++ )
{     block_buf1[j] = FILEBLK - j + K;	
}
block_buf1[NICFREE] = FILEBLK - i ;// 最末组的空闲盘块数  
bwrite( i + K, block_buf1 );
// 把超级块写入 block 1#  
fseek( fd, BLOCKSIZ, SEEK_SET );
fwrite( &filsys, 1, sizeof( struct filsys ), fd ); 
while( cmdexp() == 0 ){};	// 当用户quit时, cmdexp()返回1  
fclose( fd );
return 1;

}


```#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BLOCKSIZ 512	/*磁盘块大小 */
#define NICFREE 10      /*每组的块数 */
#define FILEBLK 25 	/*文件区磁盘块总数 */
#define K 11 	        /*文件区开始块 */
struct filsys           /*超级块部分数据结构 */
{  unsigned int s_nfree;	/*空闲盘块数 */
   unsigned short s_pfree;      /*空闲盘块号栈指针 */
   unsigned int s_free[NICFREE];/*空闲盘块号栈 */
};


struct filsys filsys;		// 超级块数据结构  
FILE *fd;
char input_buf[20];             //命令行输入缓冲区
int over;			//命令行结束标记


unsigned int balloc()
{	
	unsigned int block_buf0[BLOCKSIZ];
	unsigned int free_block, free_block_num;
	int i;
	if(filsys.s_nfree == 0)	                    // 磁盘已满,无空闲盘块  
	{
	printf( "Disk has no space\n" );
	return -1;
	}
	printf("balloc=%d\n",filsys.s_pfree);
	free_block = filsys.s_free[filsys.s_pfree];		// 取得当前空闲盘块号 
	if(filsys.s_pfree == 0)			            // 已经是栈底  
	{	
        bread(filsys.s_free[0],block_buf0);        // 调用bread读取栈底盘块号所对应的盘块数据到block_buf0中
        free_block_num=block_buf0[NICFREE];
		for(i=0;i<=block_buf0[NICFREE];i++){
				filsys.s_free[i]=block_buf0[i];
		}                                          //从block_buf0 读取该空闲盘块组的盘块数  
	                                              // 把盘块号组block_buf0数据写入到空闲盘块号栈中
        filsys.s_pfree = free_block_num - 1;	  // 指针指向栈顶  	
	}
	else
		filsys.s_pfree--;			// 栈指针下移一位  
	filsys.s_nfree--;               // 空闲盘块数减1 
	return free_block;				// 返回空闲盘块号 
}

// 空闲盘块回收函数:bfree
void bfree( unsigned int block_num )
{	int i;
	unsigned int block_buf0[BLOCKSIZ];
	if ( ( block_num<=0) || ( block_num>FILEBLK) )
	{     printf("bfree: error block_num\n");
   	   return ;
	}
	filsys.s_pfree++;		   	               // 栈指针上移一位  
	if( filsys.s_pfree == NICFREE )	    	   // 空闲盘块栈已满  
	{	
		block_buf0[NICFREE] = NICFREE;	       // 空闲盘块栈的盘块数NICFREE记入缓冲区  
        for(i=0;i<block_buf0[NICFREE];i++){
		 filsys.s_free[i]=block_buf0[i];// 把空闲盘块中数据读入缓冲区block_buf0
		}                                  
		filsys.s_pfree = 0;			           // 栈指针指向栈底  
		bwrite(block_num,block_buf0);          // 调用bwrite将缓冲区block_buf0内容写入新回收的盘块中 
	}
	filsys.s_free[filsys.s_pfree] = block_num;	// 回收盘块号 
	filsys.s_nfree++;				           // 空闲盘块加1  
}


// 将buf数据写入盘块号为ino的盘块中
void bwrite( unsigned int ino, unsigned int *  buf )
{  fseek( fd, BLOCKSIZ * ino, SEEK_SET );
   fwrite( buf, 1, BLOCKSIZ, fd );}

// 从盘块号为ino的盘块中读取数据到buf:
void bread( unsigned int ino, unsigned int *  buf )
{   fseek( fd,  BLOCKSIZ * ino, SEEK_SET );
    fread( buf, 1, BLOCKSIZ, fd );}

void display()
{  unsigned int block_buf0[BLOCKSIZ / sizeof( int )];
   //显示filsys.s_nfree、filsys.s_pfree、filsys.s_free[filsys.s_pfree];
   printf("filsys.s_nfree:%d\n",filsys.s_nfree);
   printf("filsys.s_pfree:%d\n",filsys.s_pfree);
   printf("current free:%d#\n",filsys.s_free[filsys.s_pfree]);
   int i=0;
   while ( i<=filsys.s_pfree && filsys.s_nfree>0)
   {    printf("filsys.s_free[%d]=%d \n",i,filsys.s_free[i] );
         i++;
   };
   int lastBlk=filsys.s_free[0];
   int free_block_num=NICFREE;
   while ( lastBlk>0 )
   {   bread( lastBlk, block_buf0 );
        free_block_num = block_buf0[NICFREE];
       //显示lastBlk和free_block_num 变量值;
       printf("lastBlk:%d#\n",lastBlk);
       printf("free_block_num:%d\n",free_block_num);
        for( i=0; i <free_block_num ; i++ )
        {   printf("block_buf0[%d]=%d \n",i,block_buf0[i] );}
        lastBlk=block_buf0[0];
    }  
}

void getcmd()
{  int i=0;
    while( !over )
    {   input_buf[i] = getchar();
        if( input_buf[i] == ' ' )
        {	if( i == 0 )	// 命令行的开始是空格,应舍去  
	    i--;
	else
	{   input_buf[i]='\0';
	     break;}
        }else
	if( input_buf[i] == '\n' )
	{   over = 1;
	    input_buf[i]='\0';
	    break;
	}
        i++;
     }
}

int cmdexp()
{   char buf[5];
    unsigned int d;
     over = 0;
     printf( "[@localhost]# "); // 显示命令提示行
     getcmd(); // 读取用户输入命令
     if(( strcmp( input_buf, "df" ) == 0 ))
     {	display(); //显示
	return 0;
      }
     if(( strcmp( input_buf, "alloc" ) == 0 ))
     {	balloc(); //分配
	return 0;
      }
     if(( strcmp( input_buf, "bfree" ) == 0 ))
     {  
        scanf("%d",&d);
        bfree(d); //回收
	return 0;
      }


      if( strcmp( input_buf, "exit" ) == 0 )
       {
        printf( "%s: \n", "exit" );
 	return 1;
       }
       if( input_buf[0] != '\0' ) // 找不到该命令 
       {  printf( "%s: command not found\n", input_buf );
       }
       return 0;
}



int main()
{
unsigned int block_buf1[BLOCKSIZ];
fd = tmpfile();  
char* buf = (char * )malloc((FILEBLK+K)*BLOCKSIZ );// 申请空间 
fseek( fd, 0, SEEK_SET );
fwrite( buf, 1, (FILEBLK+K)*BLOCKSIZ , fd );
free(buf);

filsys.s_nfree = FILEBLK ; // 空闲文件块数  
// 把第1组空闲盘块写入空闲盘块号栈  
int i=0;
for( i = 0; i < NICFREE; i++ )
{    filsys.s_free[i] = NICFREE - i + K - 1;
}
filsys.s_pfree = NICFREE - 1;	// 当前空闲盘块号栈指针  

int j=0;
for( i = NICFREE * 2 - 1; i < FILEBLK; i += NICFREE )
{  for( j = 0; j < NICFREE; j++ )
    {  block_buf1[j] = i - j + K;  //写下一组盘块空闲块号
     }  
    block_buf1[NICFREE] = NICFREE;  //记录本组的空闲盘块数  
    //把缓冲区内容写到每组空闲盘块号的最后一块中  
    bwrite( i - NICFREE + K, block_buf1 );
}

// 最后一组空闲盘块数可能不足NICFREE块,故需单独处理  
i = i - NICFREE;
block_buf1[0] = 0;
for( j = 1; j < FILEBLK - i; j++ )
{     block_buf1[j] = FILEBLK - j + K;	
}
block_buf1[NICFREE] = FILEBLK - i ;// 最末组的空闲盘块数  
bwrite( i + K, block_buf1 );
// 把超级块写入 block 1#  
fseek( fd, BLOCKSIZ, SEEK_SET );
fwrite( &filsys, 1, sizeof( struct filsys ), fd ); 
while( cmdexp() == 0 ){};	// 当用户quit时, cmdexp()返回1  
fclose( fd );
return 1;

}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值