实验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;
}