os操作系统实验指导(4)

2019-08-31 15:43

构成。

对目录的管理应包括的功能有: 1、对索引结点的管理

每个文件都有一唯一的磁盘索引结点(di_node)。文件被打开后,还有一个内存索引结点(i_node)。创建一新文件时,就为之建立一个磁盘索引结点,以将文件的有关信息记入其中,并将用户提供的文件名和磁盘索引结点号一并组成一个新目录项,记入其父目录文件中。文件被撤消时,系统要回收该文件的磁盘索引结点,从其父目录中删除该目录项。随着文件的打开与关闭,系统还要为之分配和回收内存索引结点。 (1)磁盘索引结点

磁盘索引结点中,包含有关文件的下述一系列信息:

文件模式di_mode。可以是正规文件、目录文件、字符特别文件、块特别文件和管道文件等几种;

文件所有者用户标识符di_uid。指拥有该文件的用户标识符;

同组用户标识符di_gid。与拥有该文件的用户在同一小组的用户标识符; 文件长度di_size。以字节计数的文件大小;

文件的联接计数di_nlink。表明在本文件系统中所有指向该文件的文件名计数;

文件的物理地址di_addr。di_addr地址项共有13项,即di_addr(0) 到di_addr(12),每个地址项占3字节;

文件的访问时间di_atime。指文件最近被进程访问的时间;

文件的修改时间di_mtime。指文件和索引结点最近被进程修改的时间; 文件的建立时间di_citime。 (2)内存索引结点 文件被打开后,系统为它在内存索引结点表区中建一内存索引结点,以方便用户和系统对文件的访问。其中,一部分信息是直接从磁盘索引结点拷贝过来的,如i_mode、i_uid、i_gid、i_size、i_addr、i_nlink等,并又增加了如下各信息: 索引结点编号i_number。作为内存索引结点的标识符;

状态i_flag。指示内存索引结点是否已上锁、是否有进程等待此i结点解锁、i结点是否被修改、是否有最近被访问等标志; 引用计数i_count。记录当前有几个进程正在访问此i结点,每当有进程访问此i结点时,对i_count+1,退出-1;

设备号i_dev。文件所属文S件系统的逻辑设备号; 前向指针i_forw。Hash队列的前向指针; 后向指针i_back。Hash队列的后向指针; (3)磁盘索引结点的分配与回收

分配过程ialloc:当内核创建一新文件时,要为之分配一空闲磁盘i结点。如分配成功,便再分配一内存i结点。其过程如下: 检查超级块上锁否。由于超级块是临界资源,诸进程必须互斥地访问它,故在进入ialloc后,要先检查它是否已上锁,若是则睡眠等待;

检查i结点栈空否。若i结点栈中已无空闲结点编号,则应从盘中再调入一批i结点号进栈。若盘中已无空闲i结点,则出错处理,返回;

从空闲i结点编号栈中分配一i结点,并对它初始化、填写有关文件的属性; 分配内存i结点;

将磁盘i结点总数-1,置超级块修改标志,返回。 回收过程ifree:

当删除文件时,应回收其所占用的盘块及相应的磁盘i结点。具体有:

检查超级块上锁否。若是,直接返回,即不把本次回收的i结点号记入空闲i结点编号栈中;

检查i结点编号栈满否。若已满,无法再装入新回收的i结点号,立即返回,若未满,便将回收的i结点编号进栈,并使当前空闲结点数+1; 置超级块修改标志,返回。

(4)内存索引结点的分配与回收 分配过程iget:

虽然iget用在打开文件时为之分配i结点,但由于允许文件被共享,因此,如果一文件已被其他用户打开并有了内存i结点,则此时只需将i结点中的引用计数+1。如果文件尚未被任何用户(进程)打开,则由iget过程为该文件分配一内存i结点,并调用bread过程将其磁盘i结点的内容拷贝到内存i结点中并进行初始化。 回收过程iput:

进程要关闭某文件时,须调用iput过程,先对该文件内存i结点中的引用计数-1。若结果为0,便回收该内存i结点,再对该文件的磁盘i结点中的连接计数减1,若其结果也为0,便删除此文件,并回收分配给该文件的盘块和磁盘i结点。 2、构造目录make_node

文件系统的一个基本功能是实现按名存取,它通过文件目录来实现。为此须使每一个文件都在文件目录中有一个目录项,通过查找文件目录可找到该文件的目录项和它的索引结点,进而找到文件的物理位置。对于可供多个用户共享的文件,则可能有多个目录项。如果要将文件删除,其目录项也应删除。

构造目录先调用ialloc为新建文件分配一磁盘i结点及内存i结点。若分配失败则返回,分配成功时须先设置内存i结点的初值(含拷贝),调用写目录过程wdir,将用户提供的文件名与分配给该文件的磁盘i结点号一起,构成一新目录项,再将它记入其父目录文件中。 3、检索目录namei

用户在第一次访问某文件时,需要使用文件的路径名,系统按路径名去检索文件目录,得到该文件的磁盘索引结点,且返回给用户一个fd。以后用户便可利用该fd来访问文件,这时系统不需再去检索文件目录。

namei根据用户给出的路径名,从高层到低层顺序地查找各级目录,寻找指定文件的索引结点号。检索时,对以'/'开头的路径名,须从根目录开始检索,否则,从当前目录开始,并把与之对应的i结点作为工作索引结点,然后用文件路径名中的第一分量名与根或与当前目录文件中的各目录项的文件名,逐一进行比较。由于一个目录文件可能占用多个盘块,在检索完一个盘块中所有目录项而未找到匹配的文件分量名时,须调用bmap和bread过程,将下一个盘块中的所有目录项读出后,再逐一检索。若检索完该目录文件的所有盘块而仍未找到,才认为无此文件分量名。 检索方式采用Hash方法。

三、主要文件操作的处理过程 1、打开文件open

检索目录。内核调用namei从根目录或从当前目录,沿目录树查找指定的索引结点。若未找到或该文件不允许存取,则出错处理返回NULL,否则转入下一步;

分配内存索引结点。如果该文件已被其它用户打开,只需对上一步中所找到的i结点引用计数+1,否则应为被打开文件分配一内存i结点,并调用磁盘读过程将磁盘i结点的内容拷贝到内存i结点中,并设置i.count=1;

分配文件表项。为已打开的文件分配一文件表项,使表项中的f.inode 指向内存索引结点;

分配用户文件描述表项。 2、创建文件creat

核心调用namei,从根目录或当前目录开始,逐级向下查找指定的索引结点。此时有以下二种情况:

重写文件。namei找到了指定i结点,调用free释放原有文件的磁盘块。此时内核忽略用户指定的许可权方式和所有者,而保持原有文件的存取权限方式和文件主。最后打开。 新建。namei未找到。调用ialloc,为新创建的文件分配一磁盘索引结点,并将新文件名及所分配到的i结点编号,写入其父目录中,建立一新目录项。利用与open相同的方式,把新文件打开。

3、关闭文件close

根据用户文件描述符fd,从相应的用户文件描述符表项中,获得指向文件表项的指针fp,再对该文件表项中的f.count-1。

四、主要数据结构 1、i节点 struct inode

{ struct inode *i_forw; struct inode *i_back; char i_flag;

unsigned int i_ino; /*磁盘i节点标号*/ unsigned int i_count; /*引用计数*/

unsigned short di_number; /*关联文件数,当为0时,则删除该文件*/ unsigned short di_mode; /*存取权限*/

unsigned short di_uid; /*磁盘i节点用户id*/ unsigned short di_gid; /*磁盘i节点组id*/ unsigned int di_addr[NADDR]; /*物理块号*/ 2、磁盘i节点 struct dinode

{ unsigned short di_number; /*关联文件数*/ unsigned short di_mode; /*存取权限*/ unsigned short di_uid unsigned short di_gid;

unsigned long di_size; /*文件大小*/ unsigned int di_addr[NADDR]; /*物理块号*/ }

3、目录项结构 struct direct

{ char d_name[DIRSIZ]; /*目录名*/ unsigned int d_ino; /*目录号*/ }

4、超级块 struct filsys

{ unsigned short s_isize; /*i节点块块数*/ unsigned long s_fsize; /*数据块块数*/ unsigned int s_nfree; /*空闲块块数*/ unsigned short s_pfree; /*空闲块指针*/ unsigned int s_free[NICFREE]; /*空闲块堆栈*/ unsigned int s_ninode; /*空闲i节点数*/ unsigned short s_pinode; /*空闲i节点指针*/ unsigned int s_inode[NICINOD]; /*空闲i节点数组*/ unsigned int s_rinode; /*铭记i节点*/

char s_fmod; /*超级块修改标记*/ }

5、用户密码 struct pwd

{ unsigned short p_uid; unsigned short p_gid; char password[PWOSIZ]; };

6、目录 struct dir

{ struct direct direct [DIRNUM]; int size; };

7、查找内存i节点的hash表 struct hinode

{ struct inode *i_forw; };

8、系统打开表 struct file

{ char f_flag; /*文件操作标志*/ unsigned int f_count; /*引用计数*/

struct inode *f_inode; /*指向内存i节点*/ unsigned long f_off; /*读/写指针*/ };

9、用户打开表 struct user

{ unsigned short u_default_mode;

unsigned short u_uid; /*用户标志*/ unsigned short u_gid; /*用户组标志*/ unsigned short u_ofile[NOFILE]; /*用户打开表*/ };

三、主要函数

1、i节点内容获取函数iget( ) 2、i节点内容释放函数iput( ) 3、目录创建函数mkdir( )

4、目录搜索函数namei( ) 5、磁盘块分配函数balloc( ) 6、磁盘块释放函数bfree( ) 7、分配i节点区函数ialloc( ) 8、释放i节点区函数ifree( )

9、搜索当前目录下文件的函数iname( ) 10、访问控制函数access( )

11、显示目录和文件用函数_dir( ) 12、改变当前目录用函数chdir( ) 13、打开文件函数open( ) 14、创建文件函数create( ) 15、读文件用函数read( ) 16、写文件用函数write( ) 17、用户登录函数login( ) 18、用户退出函数logout( )

19、文件系统格式化函数format( ) 20、进入文件系统函数install( ) 21、关闭文件系统函数close( ) 22、退出文件系统函数halt( ) 23、文件删除函数delete( ) 四、主程序说明 begin

step1 对磁盘进行格式化

step2 调用install( ),进入文件系统 step3 调用_dir( ),显示当前目录 step4 调用login( ),用户注册

step5 调用mkdir( )和chdir( )创建目录 step6 调用creat( ),创建文件0 step7 分配缓冲区 step8 写文件0

step9 关闭文件0和释放缓冲

step10 调用mkdir( )和chdir( )创建子目录 step11 调用creat( ),创建文件1 step12 分配缓冲区 step13 写文件1

step14 关闭文件1和释放缓冲

step15 调用chdir将当前目录移到上一级 step16 调用creat( ) ,创建文件2 step17 分配缓冲区

step18 调用write( ),写文件2 step19 关闭文件2和释放缓冲 step20 调用delete( ) ,删除文件0 step21 调用creat( ) ,创建文件3 step22 为文件3分配缓冲区


os操作系统实验指导(4).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:六年级下册英语素材-英语名词单复数变化规律及练习题 - 通用版

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: