操作系统大作业Linux文件管理系统.docx
《操作系统大作业Linux文件管理系统.docx》由会员分享,可在线阅读,更多相关《操作系统大作业Linux文件管理系统.docx(54页珍藏版)》请在冰豆网上搜索。
操作系统大作业Linux文件管理系统
华南理工大学软件学院
2013级操作系统大作业实验报告
课程名称:
操作系统
任课老师:
作业题目:
简单二级文件系统
班级:
学生姓名:
学号:
1.实验目的
2.实验环境
3.实验内容
4.程序中使用的数据结构及符号说明
5.源程序及注释
6.程序运行时的初值和运行结果
一、实验目的
通过一个简单多用户文件系统的设计,加深理解文件系统的内部功能及内部实现。
二、实验环境
操作系统:
Ubuntu12.04(Ubuntu/Linaro4.6.3-1ubuntu5)
编译器:
gcc4.6.3
语言:
C语言
三、实验内容
FMSV1.0系统模拟了原生的文件系统,使用文本来当作磁盘,并使用了空闲块记录表,目录,i-node等数据结构来辅助文件系统的运作。
磁盘:
一个名为blockDisk的文件,里面含有256个数据块。
每个数据块的长度为1024,可存储1024个字符。
I节点:
包含文件名,文件保护码,文件长度,文件存放位置。
目录:
一个链表,记录了i节点。
空闲块记录表FBT:
用于记录磁盘块使用情况,0表示未使用,1表示使用。
数据块:
保存了文件的数据,一个数据块至多存放一个文件。
数据块使用情况:
用于记录文件使用数据块的情况。
存放在I节点的fat数组中。
文件:
一个文件最多占用两个数据块,即长度至多为4028.
FMSV1.0系统支持的命令行:
login:
登录
register:
注册
open:
打开文件
read:
读取文件数据到屏幕
write:
写文件,分为cover和append两种类型;cover是覆盖原数据,append是在不改变原始数据的基础上进行增加。
close:
关闭文件
create:
新增文件
delete:
删除文件
exit:
退出程序
help:
帮助
四、程序中使用的数据结构及符号说明
/*---------------结构定义-----------------*/
/*---------用户--------*/
typedefstructuser
{
characcount[15];//账户最长为10
charpassword[15];//密码最长为10,多出来的是为了方便运算
}user;
/*--------数据节点--------*/
typedefstructdatanode//用于记录文件数据保存在哪个数据块的哪个范围
{
intnum;//数据块号
intbegin;//数据开始位置
intend;//数据结束位置
}datanode;
/*-------i节点--------*/
typedefstructinode
{
Charfilename[30];
Intnum;
charcode[30];//保护码
intsize;
datanodefat[MAX_DATANODE_NUM];
intnode_num;
}inode;
typedefstructdirEntry//用链表来记录I节点
{
inodeind;
structdirEntry*next;
}dirEntry;
/*-------数据块--------*/
typedefstructblock
{
charcontent[MAX_BLOCK_SIZE];//数据块内容最大长度为1025,预留最后一位用来存储’\0’,
intnum;
intoffset;//记录当前数据的数量
}block;
五、源程序及注释
head.h头文件
#include
#include
#include
#include
#defineMAX_BLOCKS_NUM256//最大数据块数量是256,则数据块总大小是256KB
#defineMAX_BLOCK_SIZE1025//数据块数据容量,一个数据块的大小是1KB,最有1位用来存储'\0',表示字符串结尾!
#defineMAX_DATANODE_NUM2//每个文件最多占用的数据块的数量
#defineMAX_INODE_NUM512//i节点的最大数目,亦即系统允许容纳文件的最大数量
#defineMAX_CACHE_NUM32//允许缓存的最大数据块数量为32个数据块,缓存为32KB
/*---------------结构定义-----------------*/
/*---------用户--------*/
typedefstructuser
{
characcount[15];//账户最长为10
charpassword[15];//密码最长为10,多出来的是为了方便运算
}user;
/*--------数据节点--------*/
typedefstructdatanode//用于记录文件数据保存在哪个数据块的哪个范围
{
intnum;//数据块号
intbegin;//数据开始位置
intend;//数据结束位置
}datanode;
/*-------i节点--------*/
typedefstructinode
{
charfilename[30];
intnum;
charcode[30];//保护码
intsize;
datanodefat[MAX_DATANODE_NUM];
intnode_num;
}inode;
typedefstructdirEntry//用链表来记录I节点
{
inodeind;
structdirEntry*next;
}dirEntry;
/*-------数据块--------*/
typedefstructblock
{
charcontent[MAX_BLOCK_SIZE];//数据块内容最大长度为1024
intnum;
boolisRevised;//用于记录数据块是否进行数据修改
intoffset;//记录当前数据的数量
}block;
/*-------------定义全局变量-------------------*/
intislogin=0;//0meansthe
charblockspath[30]="userdata/blocksDISK.disk";//所有数据(即虚拟磁盘)地址
charuserspath[30]="userdata/users.us";
staticusercurrUser;//当前用户
staticdirEntry*DIR;
staticintcurr_inode_num=0;//当前i节点数量,亦即文件数量
staticblock*cache;
intmax_node=0;//最大的inode编号
staticintFBT[MAX_BLOCKS_NUM];
staticchar*dirpath;
staticcharfbtpath[30]="userdata/FBT.disk";
staticdirEntry*selectEntry;//当selectEntry==NULL时,证明没有打开文件
staticdirEntry*currEntry;
//命令行
staticcharcm_help[10]="help";
staticcharcm_lg[10]="login";
staticcharcm_rg[10]="register";
staticcharcm_dir[10]="dir";
staticcharcm_create[10]="create";
staticcharcm_delete[10]="delete";
staticcharcm_open[10]="open";
staticcharcm_read[10]="read";
staticcharcm_write[10]="write";
staticcharcm_close[10]="close";
staticcharcm_exit[10]="exit";
staticcharcm_cancle[10]="cancle";
/*-------------函数声明---------------*/
voidcreateStyle(int,char);
voidcreateWrap(int);
intcreateSystem();
intdiskUpdate(block);
voidstart();
voidgetUser();
intlogin();
intregist();
charlgOrRg();
voidcreateBlocksDisk();
FILE*createDir();
voidinitDir(char*);
intgetAction();
voidinitFBT();//初始化数据空闲块记录表
intgetCode();
intgetFreeBlock(bool);
voidsaveDir();
voidsaveBlock(blockbk);
voidsaveFBT();
intcreateHelp(char*filename);
dirEntry*delHelp(char*filename);
voidcreateDataDir();
//响应指令的函数
intLgRg();//登录或注册
voidhelp();
voiddir();
voidcreate();
voiddel();
voidopen();
voidclose();
voidread();
voidwrite();
voidcoverHelp();
voidappendHelp();
//Linuxdoesn'tsupportthefunctionstrcmpi,soIneedtofinishitbymyself.
intstrcmpi(char*p1,char*p2)
{
if(strlen(p1)!
=strlen(p2))
{
return-1;
}
inti;
for(i=0;i{
if(p1[i]!
=p2[i])
{
return-1;
}
}
return0;
}
voidcreateDataDir()
{
char*datapath="userdata";
printf("NodataDir!
\nNowcreateit...\n");
if(mkdir(datapath,0777))
{
printf("CannotcreateDataDir...\nPleasecontactQQ878631510forhelp...\nCrtl+Ctoexit.\n");
while
(1);
}
printf("SucceedcreatingdataDir!
\n");
}
voidshowInode(inodeind)
{
printf("num:
%d\n",ind.num);
printf("filename:
%s\n",ind.filename);
printf("size:
%d\n",ind.size);
}
//界面美化函数
voidcreateStyle(intnum,charstyle)
{
while(num--)
{
printf("%c",style);
}
}
voidcreateWrap(intn)
{
while(n--)
{
printf("\n");
}
}
//辅助函数
charlgOrRg()
{
while
(1)
{
charcom[10];
printf("[login]or[register]:
");
scanf("%s",com);
if(!
strcmpi(com,cm_lg))
{
return'l';
}
if(!
strcmp(com,cm_rg))
{
return'r';
}
}
}
voidhelp()
{
printf("欢迎您使用FMS文件系统模拟系统V1.0");
printf("以下是本系统支持的指令:
\n");
printf("exit:
退出\n");
printf("help:
帮助\n");
printf("dir:
查看目录中的所有文件\n");
printf("create:
新建文件\n");
printf("delete:
删除文件\n");
printf("open:
打开文件\n");
printf("read:
读文件(必须先打开文件)\n");
printf("write:
写文件(必须先打开文件)\n");
printf("close:
关闭文件\n");
}
voidcreateBlocksDisk()
{
//初始化磁盘块
FILE*fp=fopen(blockspath,"w");
if(fp==NULL)
{
printf("CannotcreateDisk!
\nCtrl+Ctoquit\n");
while
(1);
}
else
{
inti,j;
for(i=0;i{
for(j=0;j{
fputc('$',fp);
}
}
fclose(fp);
}
FILE*p=fopen(fbtpath,"w");
if(p==NULL)
{
printf("FBTCreatedERROR!
\n");
while
(1);
}
else
{
inti;
for(i=0;i{
FBT[i]=0;
fprintf(p,"%d",0);
}
fclose(p);
}
}
dirEntry*isInDir(char*filename)
{
inti;
dirEntry*pt=DIR;
while(pt!
=NULL)
{
if(!
strcmpi(pt->ind.filename,filename))
{
returnpt;
}
pt=pt->next;
}
returnNULL;
}
dirEntry*delHelp(char*filename)
{
dirEntry*res=DIR;
if(res==NULL)
{
printf("Nofiles!
\n");
returnres;
}
if(res->next==NULL)
{
if(!
strcmpi(res->ind.filename,filename))
{
DIR=NULL;
currEntry=NULL;
printf("删除成功!
\n");
returnres;
}
else
{
returnNULL;
}
}
if(!
strcmpi(res->ind.filename,filename))
{
DIR=res->next;
printf("删除成功!
\n");
returnres;
}
while(res->next!
=NULL)
{
if(!
strcmpi(res->next->ind.filename,filename))
{
dirEntry*r=res->next;
res->next=r->next;
printf("删除成功!
\n");
returnr;
}
res=res->next;
}
printf("删除失败!
\n");
returnNULL;
}
voidcoverHelp()
{
//释放原数据块,更新FBT
intf;
if(selectEntry->ind.size!
=0)//要size>0才会分配数据块
{
for(f=0;find.node_num;f++)
{
FBT[selectEntry->ind.fat[f].num]==0;
}
}
charcontent[MAX_DATANODE_NUM][MAX_BLOCK_SIZE];
chartmp;
inodeind;
printf("Endwith'$'\n");
inti=0;
while((tmp=getchar())!
='$')
{
if(i==0&&tmp=='\n')
{
continue;
}
content[i/MAX_BLOCK_SIZE][i++]=tmp;
}
ind.size=i;
//此时已经结束输入
if(i>(MAX_BLOCK_SIZE-1)*MAX_DATANODE_NUM)
{
printf("文件过大,无法存储,创建失败!
\n");
return;
}
intk;
for(k=0;k<=i/(MAX_BLOCK_SIZE-1);k++)
{
blockbk;
intbkn;
for(bkn=0;bkn{
bk.content[bkn]='$';
}
bk.content[MAX_BLOCK_SIZE-1]='\0';
//printf("bk.content:
%s\n",bk.content);
char*tmp;
inttp=0;
intlen=0;
if(k==0)
{
if(i{
len=i;
}
}
if(k==1)
{
len=i%(MAX_BLOCK_SIZE-1)+1;
}
for(tp=0;tp{
bk.content[tp]=content[k][tp];
}
bk.isRevised=true;
if(k==0)
{
bk.num=getFreeBlock(false);
}
else
{
bk.num=getFreeBlock(true);
if(bk.num==-1)
{
printf("数据块已用完,内存不足!
\n");
return;
}
}
saveBlock(bk);
ind.fat[k].num=bk.num;
ind.fat[k].begin=0;
ind.fat[k].end=len;
}
ind.node_num=k;
strcpy(ind.code,selectEntry->ind.code);
strcpy(ind.filename,selectEntry->ind.filename);
ind.num=selectEntry->ind.node_num;
selectEntry->ind=ind;
saveDir();
saveFBT();
printf("文件已保存!
\n");
}
voidappendHelp()
{chartmp[MAX_BLOCK_SIZE*2];
charch;
printf("Endwith'$':
\n");
inti=0;
while((ch=getchar())!
='$')
{
if(i==0&&ch=='\n')
{
continue;
}
tmp[i++]=ch;
}
tmp[i]='\0';
//此时已经完成输入
if((i+selectEntry->ind.size)>(MAX_BLOCK_SIZE-1)*MAX_DATANODE_NUM)
{
printf("文件过大,无法存储,创建失败!
\n");
return;
}
else
{
if(selectEntry->ind.size>MAX_BLOCK_SIZE-1)//已经占用了两个block
{
intoffset=selectEntry->ind.size-MAX_BLOCK_SIZE+1;
FILE*bfp=fopen(blockspath,"r+");
if(bfp==NULL)
{
printf("DISKERROR!
\nFromappendFile...\n");
return;
}
else
{
fseek(bfp,(selectEntry->ind.fat[1].num*(MAX_BLOCK_SIZE-1)+offset),SEEK_SET);
fwrite(tmp,sizeof(char),i,bfp);
fclose(bfp);
selectEntry->ind.size=selectEntry->ind.size+i;
selectEntry->ind.fat[1].end=selectEntry->ind.fat[1].end+i;
saveDir();
printf("文件保存成功!
\n");
}
}
el