文件系统代码:

一、 实验目的

  1. 通过阅读和调试文件管理的模拟程序以加深对文件系统的理解。

二、 实验要求

  1. 每个小组给出该模拟文件系统中的各个模块的流程图及其各模块之间关系的说明(电子版)。
  2. 修改程序中的错误,调试完善模拟程序;
  3. 增加新的功能

三、 程序流程

流程图:

[1] user&password

[2] exit&cd

[3] mkdir&mkfile

[4] dir&del

stress模拟磁盘io升高_操作系统


stress模拟磁盘io升高_stress模拟磁盘io升高_02


[5] read&write

(1) read filename bytes,读取文件内容。

stress模拟磁盘io升高_文件管理_03


(2) write filename bytes,写文件。

stress模拟磁盘io升高_操作系统_04

四、 程序改错

(1) 当重复写入一个文件时,会先释放之前占用的盘块,再重新分配盘块,但是在显示的时候会出现乱序(open.cpp)

stress模拟磁盘io升高_文件系统_05


(1)原因分析:在释放之前占用盘块的时候,是从最开始的盘块先释放的,依次压入空闲栈,但是栈是先进后出,所以后面分配的时候就是先分配最后一个进栈的盘块。修改空闲盘块进栈的顺序即可。(2)修改:

stress模拟磁盘io升高_Linux_06


(3)改后结果

stress模拟磁盘io升高_Linux_07

(2) 重复创建文件目录时提示错误;重复创建同一个文件时出错。

stress模拟磁盘io升高_文件系统_08


a) 原因分析:

问题出在iget函数中,第一次创建的目录时已经有了对应的内存节点,因此第二次创建目录时,应该获取目录名称所对应的内存节点,即dir.direct[dirid].d_ino而不是dirid作为iget函数的参数,再将此内存节点的类型与DIDIR进行比较。

b) 修改如下:

  1. Create.cpp
  2. Dir.cpp
  3. Shell.cpp

    c) 改后结果:

    (3) Dir命令,显示当前目录一直是“…”,请修改为正确的当前路径。
    a) 原因分析:
    dir.direct[1]中每次都存的是当前目录中存储的信息,每次使用cd命令时,会将当前目录名变成".",所以需要事先保存未进入前的该目录名。
    b) 修改如下:
    增加一个数组,用来储存当前目录名称, 在使用cd命令时,将目录名储存到该数组

    代码如下

    在使用dir命令时,输出该数组。
    c) 改后结果:

    (4) ch /dir反序问题:(dir.cpp)

(1)原因分析:

cd切换时,会更新dir.direct数组,把所有空的内容都移到最后。具体操作是:从最后一个开始找,找到一个有内容的,然后将该位置的内容复制到之前空的位置。

stress模拟磁盘io升高_stress模拟磁盘io升高_09


(2)修改如下:每次先找到一个空的位置,然后找寻后面非空的位置,然后将该位置的内容复制到之前空的位置。

stress模拟磁盘io升高_文件系统_10


(3)修改后结果:

stress模拟磁盘io升高_Linux_11


(5) 当创建同名文件时,显示盘块的时候会出现乱序

stress模拟磁盘io升高_操作系统_12


(1)原因分析:

create函数中既调用bfree函数又调用open函数,分别顺序和逆序回收文件a的盘块,即回收两次。重写并覆盖文件a(记为文件a')时,write函数里会调用balloc函数,从空闲栈中获取并分配盘块。

(2)修改如下:

stress模拟磁盘io升高_文件管理_13


此处将create中的bfree函数删除,减少一次对bfree函数的调用,且保持倒序回收。

(3)改后结果:

stress模拟磁盘io升高_文件管理_14


(6) 在根目录下面创建子目录a,在a中创建文件b并写于大于一个块(512字节)的内容,之后返回根目录,查看目录内容的时候,会出现错误(rdwt.cpp)

stress模拟磁盘io升高_stress模拟磁盘io升高_15


(1) 原因分析:

write写入一个文件超过512个字节时,写入磁盘的时候写错了地方,导致覆盖了之前位置的内容。(2) 修改如下:

stress模拟磁盘io升高_stress模拟磁盘io升高_16


(3) 修改后结果:

stress模拟磁盘io升高_Linux_17


五、 新增功能

  1. 增加添加用户,修改权限,删除用户,修改密码功能。

①初始化用户信息,格式为“用户名-权限-密码”

stress模拟磁盘io升高_Linux_18

②读取文件中的用户信息

stress模拟磁盘io升高_文件系统_19


③在user.cpp中通过useradd、userauth、userdel、passwd函数增加或修改文件中的信息。(这里展示部分代码)

stress模拟磁盘io升高_文件管理_20


④成果展示:

登录:

stress模拟磁盘io升高_文件系统_21


添加用户:

stress模拟磁盘io升高_文件系统_22


修改权限:

stress模拟磁盘io升高_Linux_23


删除用户:

stress模拟磁盘io升高_文件系统_24


修改密码:

stress模拟磁盘io升高_操作系统_25


2. 增加查看当前用户信息的新功能

在命令行中输入“who”,可以显示当前用户的所有信息,包括这个用户的id号、登录密码、所属用户组。

stress模拟磁盘io升高_操作系统_26


运行结果:

stress模拟磁盘io升高_操作系统_27


3. 删除目录

(1) 修改原来的delete函数,在if条件判断不是文件是目录之后,增加一个确认是否需要删除目录。

stress模拟磁盘io升高_文件系统_28


(2) 确认删除目录之后,将调用新的函数delete_dir(),将需要删除的filename参数传递给这个新的函数,进入函数之后首先需要判断这个目录是不是一个空的目录,若为空的目录则回到上一层目录直接删除这个空目录

stress模拟磁盘io升高_文件系统_29


(3) 若目录不为空则以当前这个目录长度为范围依次遍历,注意起始位置为2,需要跳过上层目录和当前目录。遍历的时候同样需要判断是文件还是目录,如果是文件就直接删除。

stress模拟磁盘io升高_操作系统_30


(4) 是子目录,同样步骤,空则直接删除,非空则在子目录内递归删除

stress模拟磁盘io升高_文件系统_31


(5) 验证:

在主目录下创建目录a,b,进入目录a创建目录c和文件d,回到主目录,删除目录a,再次显示当前目录。目录a以及目录内容已经成功删除,并且目录b没有受到影响

stress模拟磁盘io升高_文件系统_32


4. 增加 help 命令。

直接在shell.cpp中进行添加:

stress模拟磁盘io升高_Linux_33


执行结果:

stress模拟磁盘io升高_Linux_34


5. 写文件的时候输入文本内容

stress模拟磁盘io升高_文件管理_35


读文件的时候输出文本内容:

stress模拟磁盘io升高_操作系统_36


结果:

stress模拟磁盘io升高_Linux_37


六、 实验总结

通过阅读和调试文件管理的模拟程序,我们加深了对文件系统的理解,在实验中小组合作使我们明白小组分工明确的重要性,也懂得了有效交流的重要性,通过调试代码,运行测试,能够加快理解代码的思想。