1、2014-2015(1)操作系统原理课程大型实验模拟 Unix 文件系统目录模拟 Unix 文件系统 .0一 实验介绍 2(1) 文件卷结构设计 .2(2) I 节点结构设计 2(3) 目录结构 2(4) 用户及组结构 .2二 实验环境 2三 实验设计 33.1 系统流程 .43.2 文件结构 .53.3 实现命令操作 .5四 数据结构 641 超级块 .642 I 节点 .643 目录 .744 用户文件表 .745 用户和组 .7五 模块详解 85.1 文件、目录和文件表操作 85.2 i 节点操作 .85.3 块操作 85.4 具体命令操作 .95.5 主函数和所有命令操作的函数 95.
2、6 其他函数 .9六 实验演示 96.1 登录 .96.2cat 操作 .96.3cd 操作 .106.4ls 操作 .106.5chgrp 操作 .106.6chown 操作 .106.7chmod 操作 .106.8touch 操作 .106.9mkdir 操作 .106.10rmdir 操作 .116.11rm 操作 .116.12ln 操作 .116.13mv 操作 .116.14cp 操作 .116.15passwd 操作 .116.16pwd 操作 .126.17umask 操作 .12七 实验总结 12一 实验介绍(1) 文件卷结构设计0# 1# K# K+1# K+2# K+3
3、# n#K=12,n=2048(2) I 节点结构设计文件大小文件联接计数文件地址文件拥有者文件所属组文件权限及类别文件最后修改时间其中文件地址为六项:四个直接块号,一个一次间址,一个两次间址(3) 目录结构用 16 字节表示,其中 14 字节为文件名,2 字节为 I 节点号(4) 用户及组结构用户信息中包括用户名、口令,所属组,用户打开文件表(文件树结构应与用户相对应:有每个用户的 HOME 目录)组信息中可只包含组名,组号。二 实验环境Linux 操作系统,标准 c89i 节点区 数据区管理区三 实验设计3.1 系统流程NYNYNYNNYY开始输出登录选 1,初始化选 2输入一个整型 ii
4、=2?i0?初始化程序结束i=1?进入登录程序登录成功?进入命令操作程序是否退出?结束结束3.2 文件结构1基本思路:用硬盘上的一个文件(funix.txt)来模拟一个文件卷。2磁盘块的设计:每块 512 个字节,一共 2048 块,数据区占用 2035 块,I 节点占用 12 块,每个 i 节点占 48个字节,一共 128 个 i 节点,超级块占第 0 块。3空闲磁盘块:采用成组链接法管理。每组 10 块,格式化时假设所有块都分配了出去,将所有块按从大到小的顺序依次压入。 4I 结点管理:采用位示图法,注意此时位示图不表示空闲块,只表示相应的 i 节点号是否被利用,如果被利用相应的 i 节点
5、号对应位示图的那一位为 1,如果没有被利用则对应的位为 0。3.3 实现命令操作命令格式ls 显示文件目录chmod 改变文件权限chown 改变文件拥有者chgrp 改变文件所属组pwd 显示当前目录cd 改变当前目录mkdir 创建子目录rmdir 删除子目录umask 文件创建屏蔽码mv 改变文件名cp 文件拷贝rm 文件或目录删除ln 建立文件联接cat 连接显示文件内容passwd 修改用户口令touch 创建文件vi 编写文件内容四 数据结构41 超级块#ifndef SUPERstruct superunsigned int csize;/文件系统的总块数(4)unsigned
6、short bsize;/每块的字节数(2)unsigned int dsize;/数据块的块数(4)unsigned int dbeg;/数据块的起始块号(4)unsigned int demp;/空闲盘块数(4)unsigned short isize; /i 节点块的总块数(2)unsigned int ibeg;/i 节点的起始块号(4)unsigned short inum;/i 节点的个数(2)unsigned short i8;/i 节点位示图(12)unsigned short iclock;/inode 锁(2)unsigned int mfsize;/文件的最大所占字节数(
7、4)unsigned short bmf;/文件的最大所占块数(2)time_t bu;/修改时间(8)short dssize;/当前空闲盘块好栈中的空闲盘块数目(2)unsigned int dssDS_size;/(400)unsigned short dsclock;/成组链接锁(2)sup;#endif42 I 节点/外存 i 节点#ifndef INODEstruct inodeunsigned int fsize;/文件大小(4)unsigned short fln;/文件连接数(2)char gid;/文件所属组 id(1)char uid;/文件拥有者 id(1)int fm
8、ode;/文件的类型和权限(4)time_t itime;/文件最后修改时间(8)unsigned int addr6;/文件地址(24);#endif/内存 i 节点#ifndef MINODEstruct minodeint iid;/i 节点号struct inode in;/读入内存的外存 i 节点/char chflg;/是否被修改unsigned short mico;/(未用到)进程连接的个数;#endif43 目录/目录#ifndef LISTstruct listchar ls_name14:/文件或目录名;unsigned short ib;/对应的 i 节点号/;#end
9、if44 用户文件表#ifndef LS_MINODEstruct ls_minodeunsigned int f_offest:/文件相对起始位置的偏移;int f_flag:/文件的存取权限;unsigned short f_count:/打开这个文件的操作的个数;struct minode* mi:/内存 i 节点;f_inode50;#endif45 用户和组外存用户信息#ifndef USERstruct userchar username14;/用户名char uid;/用户 idchar grpname14;/组名char gid;/组 idint umask;/屏蔽码char
10、password20;/密码char homedir50;/家目录;#endif/内存用户信息#ifndef MUSERstruct muserstruct user us: /读入内存的外存用户信息;int off_t:/用户信息在外存 etc 文件中的位置;int fd;/当前目录在文件表中的位置:mus;#endif五 模块详解5.1 文件、目录和文件表操作(经过 i 节点模块封装后这一层的所有操作都感觉是对文件中的每一个字节进行操作)int search(char *,int);/查找单个目录下文件或子目录的函数int iname(char *);/从根目录查找整个目录函数int re
11、adf(int fd, char *buf, int count);/读文件中的内容 dint writef(int fd, const char *buf, int count);/将内容写入文件 eint openf(const char *pathname, int flags);/查找目录找到文件后写入文件表 nint creatf(const char *pathname, int mode);/创建文件或目录 tint linkf(const char *oldpath, const char *newpath);/联接文件 kint unlinkf(const char *pat
12、hname);/删除联接 kint closef(int fd);/关闭文件 e5.2 i 节点操作(1、主要负责将所有上层对字节的操作转化为对块的操作2、文件的底层建立和删除)int iread(int i,struct inode * ); 读入外存 inode;int iwrite(int i,struct inode * );写出外存 inode;int ialloc(struct iuser ius);申请 inode;int ifree(int i);释放 inode; struct minode * i_get(int i);/获取内存 inodeint i_put(struct
13、 minode *);/删除内存 inode;int getblock(unsigned int offset,struct inode);/寻找文件物理块函数int ifadd(unsigned int size,struct minode *);/将文件的字节的加长转化为对物理块的增加了int ifsub(unsigned int size,struct minode *);/文件的减短改变为对物理块的减少int subblock(unsigned int offset,struct inode in);/删除文件块子函数5.3 块操作unsigned int balloc();/分配一个
14、块int brelse(unsigned int b);/回收一个块int bread(int b,unsigned short seek,unsigned short m,void *buf);/读取块中的内容int bwrite(int b,unsigned short seek,unsigned short m,const void *buf);/写入块中的内容int set_ds();/成组链接的初始化函数;5.4 具体命令操作void ls();/显示文件目录void cd(char *);/改变当前目录void u_umask(int);/文件创建屏蔽码void passwd(co
15、nst char *);/修改用户口令void u_chmod(char *,int);/改变文件权限void pwd();/显示当前目录void u_chown(char *,char);/改变文件拥有者void u_chgrp(char *,char);/改变文件所属组void u_touch(char *);/新建文件void rm(char*);/文件删除void u_mkdir(char *);/创建子目录void u_rmdir(char *);/删除子目录void vi(char *);/编写文件内容void u_cat(char*);/连接显示文件内容void u_mv(cha
16、r*,char*);/改变文件名void u_ln(char*,char*);/建立文件联接void u_cp(char*,char*);/文件拷贝5.5 主函数和所有命令操作的函数int bash(char * );/ 所有命令操作的函数 exit 退出命令操作函数;int main(void);/主函数进行登录和格式化或进入所有命令操作的函数5.6 其他函数int init();初始化函数/int login();登录函数/int shutdown();/退出系统的函数/六 实验演示6.1 登录6.2cat 操作6.3cd 操作6.4ls 操作6.5chgrp 操作6.6chown 操作6
17、.7chmod 操作6.8touch 操作6.9mkdir 操作6.10rmdir 操作6.11rm 操作6.12ln 操作6.13mv 操作6.14cp 操作6.15passwd 操作6.16pwd 操作6.17umask 操作七 实验总结经过 4 周的共同努力,我们将程序按要求编写、修改完善,使其能实现课程设计要求的基本功能并增加了一个新的功能(新建文件)。操作系统是计算机科学与技术专业中的一门重要基础课,目的是让我们了解操作系统的基本概念,理解计算机系统的资源如何组织,操作系统如何有效地管理这些系统资源,用户如何通过操作系统与计算机系统打交道。通过课程设计,可以进一步理解在计算机系统上运
18、行的其它各类操作系统,并懂得在操作系统的支持下建立自己的应用系统。操作系统课程设计,对于训练我们掌握程序设计、熟悉上机操作和程序调试技术都有重要作用。重点培养我们的思维能力、创新能力和排错能力。通过课程设计,进一步融会贯通教材内容,掌握程序各功能模块的工作原理,相互联系和来龙去脉,完整地建立系统的概念。激发我的学习热情和主动性,培养我的独立工作能力,在实践活动中,将所学知识综合运用,增长才干,并积累经验。对编程语言又有了更深一层次的认识,并对其的编程能力有所加强,但还是很多的不足有待改进,对于编程来说还需要大量的实践,才能在发现问题和解决问题中前进与提高。最后,祝老师新年快乐,身体健康,工作顺
19、利,万事如意!八 代码/* block.c* Created on: 20141227* Author: sunb*/#include#include“super.h“#include “block.h“#include“inode.h“#include int bread(int b,unsigned short seek,unsigned short m,void *buf )/off_t ls=(b-1)*B_size+D_beg*B_size+seek;size_t co=m;int l = pread(fd, buf, co, ls);return l;int bwrite(int
20、b,unsigned short seek,unsigned short m,const void *buf)/off_t ls=(b-1)*B_size+D_beg*B_size+seek;size_t co=m;int l = pwrite(fd, buf, co, ls);return l;unsigned int balloc()unsigned int block=0;if(sup.dssize+10)block=sup.dsssup.dssize;sup.dssize-;sup.demp-;if(sup.dss0!=0bread(block,0,DS_size*4,sup.dssi
21、ze=DS_size-1;sup.demp-;else if(sup.dss0=0return block;int brelse(unsigned int b )if(b0)int ft=brelse(i);/*printf(“%dt“,ft);if(ft%30=0)puts(“n“);*/*while(sup.dssize0)sup.dsssup.dssize=i;sup.dssize+;i-;if(sup.dssize=DS_size)/bwrite(int b,unsigned short seek,unsigned short m,const char *buf)int f=DS_si
22、ze;while(f-)printf(“%dt“,sup.dssDS_size-f-1);if(i0)bwrite(i,0,4*DS_size,sup.dssize=0;if(sup.dssize!=0)sup.dssize-;*/i-;puts(“n“);return 0;/* block.h* Created on: 2014 年 12 月 27 日* Author: sunb*/#ifndef BLOCK_H_#define BLOCK_H_#ifndef ZBLOCKstruct zblockunsigned int dss100;/(400);#endifunsigned int b
23、alloc();/块分配/int iballoc(struct inode *,unsigned int);int brelse(unsigned int b);/块回收int bread(int b,unsigned short seek,unsigned short m,void *buf);/块读int bwrite(int b,unsigned short seek,unsigned short m,const void *buf);/块写int set_ds();#endif /* BLOCK_H_ */* file.c* Created on: 2015 年 1 月 2 日* Au
24、thor: sunb*/#include#include“super.h“#include“user.h“#include“inode.h“#include“list.h“#include“block.h“#include“file.h“#includevoid getfid(struct list ls)int il=0,ki=0,lfb=-1,lfc=-1;f_inodelfd.f_offest=0;while(iliid)=ls.ib)lfb=il;break;else if(ki=0)lfc=il;ki=1;il+;if(lfc=0if(f_inodelfb.mi-in.fmodelf
25、f=lfd;lfd=lfb;else lfb=-1;int l_readf( int fd,void *buf, int count)unsigned short seek=(unsigned short)f_inodefd.f_offest%B_size;int b=0;if(f_inodefd.f_offestin.fsizeunsigned short m=(unsigned short)count;int bd=bread(b,seek, m,buf );return bd;return 0;int readf(int fd, char *buf, int count)if(f_ino
26、defd.f_flagif(f_inodefd.f_offest+countf_inodefd.mi-in.fsize)count=f_inodefd.mi-in.fsize - f_inodefd.f_offest;int t=B_size-f_inodefd.f_offest%B_size;if(t=count)f_inodefd.f_offest=f_inodefd.f_offest+l_readf(fd,buf,count);elseint i=0;if(t0)if(countB_size)f_inodefd.f_offest=f_inodefd.f_offest+l_readf(fd
27、,(buf+i),B_size);count=count-B_size;i=i+B_size;elsef_inodefd.f_offest=f_inodefd.f_offest+l_readf(fd,(buf+i),count);i=i+count;count=0;fi=f_inodefd.f_offest-fi;return fi;return 0;int l_writef(int fd,const void *buf, int count)unsigned short seek=(unsigned short)f_inodefd.f_offest%B_size;int b=0;int bd
28、=0;b=getblock(f_inodefd.f_offest/B_size,f_inodefd.mi-in);unsigned short m=(unsigned short)count;bd=bwrite(b,seek, m,buf );return bd;int writef(int fd, const char *buf, int count)if(f_inodefd.f_flagif(f_inodefd.f_offest+countf_inodefd.mi-in.fsize)ifadd(f_inodefd.f_offest+count-f_inodefd.mi-in.fsize,f
29、_inodefd.mi);f_inodefd.f_offest=fi;int t=B_size-f_inodefd.f_offest%B_size;if(t0)if(countB_size)f_inodefd.f_offest=f_inodefd.f_offest+l_writef(fd,(buf+i),B_size);count=count-B_size;i=i+B_size;elsef_inodefd.f_offest=f_inodefd.f_offest+l_writef(fd,(buf+i),count);i=i+count;count=0;elsef_inodefd.f_offest
30、=f_inodefd.f_offest+l_writef(fd,buf,count);fi= f_inodefd.f_offest-fi;return fi;return 0;int search(char *fname,int si)int j=0;if(f_inodelfd.mi!=NULL)struct list ls;if(f_inodelfd.mi-in.fmodewhile(jin.fsize)readf(lfd,if(strcmp(ls.ls_name,fname)=0)getfid(ls);return FOUND;j=j+si;return NOFOUND;int iname
31、(char *route)int i;char *namel=(char*)malloc(14);if(*route=/|*route=)lfd=0;f_inodelfd.f_offest=0;f_inodelfd.f_count=1;while(*route!=0)route+;for(i=0;i0)struct list *ls=(struct list *)malloc(sizeof(struct list);ls-ib=f;strcpy(ls-ls_name,namel);f_inodelfd.f_flag=(f_inodelfd.f_flag|02);writef(lfd,ls,16
32、);free(ls);free(namel);return f;free(namel);return -1;free(namel);return -2;free(namel);return -3;free(namel);return -4;int testmode(int flag,int fid)int fig;if(f_inodefid.mi-in.uid=mus.us.uid)fig=f_inodefid.mi-in.fmode6;fig=flagelse if(f_inodefid.mi-in.gid=mus.us.gid)fig=f_inodefid.mi-in.fmode3;fig
33、=flagelsefig=f_inodefid.mi-in.fmode;fig=flagreturn fig;int openf(const char *pathname, int flags)if(*pathname=/else if(iname(pathname)=1)int fig=testmode(flags,lfd);if(fig0)f_inodelfd.f_count=1;f_inodelfd.f_offest=0;f_inodelfd.f_flag=fig;return lfd;elseputs(“权限不足n“);return -1;elseputs(“找不到文件或无法打开n“)
34、;return -1;int closef(int fd)if(f_inodefd.mi!=NULL)i_put(f_inodefd.mi);f_inodefd.f_offest=0;f_inodefd.mi=NULL;return 0;return -1;int creatf(const char *pathname, int mode)struct iuser iu;iu.gid=mus.us.gid;iu.uid=mus.us.uid;iu.mode=(mus.us.umask)char * fname=(char *)malloc(100);strcpy(fname,pathname)
35、;int ii=l_creatf(fname, iu);if(ii0)int ifd= openf(fname,06);free(fname);return ifd;free(fname);return lfd;int unlinkf(const char *pathname)char * fname=(char *)malloc(100);strcpy(fname,pathname);int gfd=openf(fname,06);if(gfd0)f_inodegfd.mi-in.fln-;if(f_inodegfd.mi-in.fln=0)ifsub(f_inodegfd.mi-in.fs
36、ize,f_inodegfd.mi);ifree(f_inodegfd.mi-iid);i_put(f_inodegfd.mi);f_inodegfd.mi=NULL;struct list *lis=(struct list*)malloc(sizeof(struct list);int bo=0;f_inodelff.f_offest=0;int jj=0;while(jjyy)bnameyy=fnamejj+yy;yy+;bnameyy=0;while(readf(lff,lis,sizeof(struct list)int rd;if(bo=1)f_inodelff.f_offest=
37、rd;writef(lff,lis,sizeof(struct list);f_inodelff.f_offest=rd+2*sizeof(struct list);if(strcmp(lis-ls_name,bname)=0)bo=1;rd=f_inodelff.f_offest-sizeof(struct list);if(bo=1)ifsub(sizeof(struct list),f_inodelff.mi);f_inodelff.f_offest=0;free(lis);close(gfd);free(fname);return 0;free(fname);return -1;int
38、 linkf(const char *oldpath, const char *newpath)char * fname=(char *)malloc(100);strcpy(fname,oldpath);int gfd=openf(fname,06);if(gfd0)char *aname=(char *)malloc(100);strcpy(aname,newpath);if(iname(aname)=0)int jj=0;while(jjyy)bnameyy=anamejj+yy;yy+;bnameyy=0;int dff=openf(aname,06);struct list *ls=
39、(struct list *)malloc(sizeof(struct list);ls-ib=f_inodegfd.mi-iid;f_inodegfd.mi-in.fln+;strcpy(ls-ls_name,bname);f_inodedff.f_offest=f_inodedff.mi-in.fsize;writef(dff,ls,16);free(ls);free(fname);free(aname);return 0;elseprintf(“文件以存在n“);free(aname);free(fname);return -1;/* file.h* Created on: 2015 年
40、 1 月 2 日* Author: sunb*/#ifndef FILE_H_#define FILE_H_#define FOUND 1/找到目录#define NOFOUND 0/没找到#define LG 1/新建#define NOLG 0/查找/目录int lfd;int lff;int testmode(int,int);/测试是否可以对文件进行操作void getfid(struct list );int l_readf(int fd, void *buf, int count);/读取转化函数int l_writef(int fd,const void *buf, int co
41、unt);/写入转化函数int search(char *,int);/查找目录函数int iname(char *);/查找整个目录函数int l_creatf(const char *pathname, struct iuser ius);/创建文件/*模拟系统程序接口*/int openf(const char *pathname, int flags);/openint readf(int fd, char *buf, int count);/readint writef(int fd, const char *buf, int count);/writeint creatf(cons
42、t char *pathname, int mode);/creatint linkf(const char *oldpath, const char *newpath);/linkint unlinkf(const char *pathname);/unlinkint closef(int fd);/close#endif /* FILE_H_ */*=Name : funix.cAuthor : sunboVersion :Copyright : Your copyright noticeDescription : Hello World in C, Ansi-style=*/#inclu
43、de #include #include #include #include“super.h“#include“user.h“#include“inode.h“#include“list.h“#include“block.h“#include“file.h“#include“init.h“int bash(char * );int main(void)fd=open(“funix.txt“,O_RDWR);openf(“/“,06);int i=0;while(i=0)puts(“初始化输入 2 、登陆输入 1“);scanf(“%d“,if(i=2)init();else if(i=1)if
44、(login()=0)close(fd);return 0;elsechar * shell=(char *)malloc(12);while(strcmp(shell,“exit“)!=0)printfdir();scanf(“%s“,shell);bash(shell);free(shell);shutdown();puts(“!Hello World!“);close(fd);return EXIT_SUCCESS;int bash(char * shell)if(strcmp(shell,“cd“)=0)char *routel=(char*)malloc(140);scanf(“%s
45、“,routel);cd(routel);free(routel);else if(strcmp(shell,“umask“)=0)int um;scanf(“%o“,u_umask(um);else if(strcmp(shell,“passwd“)=0)char * ps=(char*)malloc(20);scanf(“%s“,ps);passwd(ps);free(ps);else if(strcmp(shell,“ls“)=0)ls();else if(strcmp(shell,“chmod“)=0)char * chmode=(char*)malloc(140);int mod;s
46、canf(“%s%o“,chmode,u_chmod(chmode,mod);free(chmode);else if(strcmp(shell,“pwd“)=0)pwd();else if(strcmp(shell,“chown“)=0)char * chmode=(char*)malloc(140);scanf(“%s“,chmode);char own2;scanf(“%s“,u_chown(chmode,(*own)-0);free(chmode);else if(strcmp(shell,“chgrp“)=0)char * grp=(char*)malloc(140);scanf(“
47、%s“,grp);char g2;scanf(“%s“,u_chgrp(grp,(*g)-0);free(grp);else if(strcmp(shell,“touch“)=0)char * grp=(char*)malloc(140);scanf(“%s“,grp);u_touch(grp);free(grp);else if(strcmp(shell,“rm“)=0)char * grp=(char*)malloc(140);scanf(“%s“,grp);rm(grp);free(grp);else if(strcmp(shell,“mkdir“)=0)char * mkr=(char*)malloc(140);scanf(“%s“,mkr);u_mkdir(mkr);free(mkr);else if(strcmp(shell,“rmdir“)=0)char