这是我的操作系统课程设计。题目是要求实现类 unix 文件系统,并且:
- 采用索引节点储存文件系统。根据课本的解释,索引节点储存另外文件控制块 FCB 中除文件名之外的内容。
- 采用混合分配方式组织文件数据。
- 采用成组链接法管理空闲的数据块。
在开始设计程序时,就考虑到的特性:
程序能够在多种抽象磁盘上建立文件系统。其中,抽象磁盘可以是:
- 真正的磁盘
- 主操作系统中的一个大文件 但是实际上,任何能够看成一系列扇区组合的并且支持对某个扇区进行读写操作的对象,都能视为抽象磁盘,从而基于此建构整个文件系统。
程序能够将不同的磁盘挂载到不同盘符(类似 Windows 系统的盘符),在通过路径操作文件时,程序能自动根据盘符识别具体的文件系统类型,从而执行对应的操作。 一个磁盘可以格式化为一个文件系统,一个磁盘可以挂载到一个盘符。程序支持多种文件系统,如:
- FAT32
- ext3
- ext4
- fulfs 由于此课程设计的目标是实现类 unix 文件系统(在这次课程设计里将其命名为 fulfs),因此实际上只实现了 fulfs。 但是理论上能够进行方便的扩展支持其它的各种文件系统。
由于第 2 点的设计需要,程序必须提供一组抽象的接口用于根据文件路径来操作文件系统而不用关心文件系统的具体类型。 因此,程序封装了一组接口,并且为了对使用者友好,其接口形式尽量模仿了 linux 系统调用。
- 提供了一个 shell 用于操作挂载的文件系统。shell 的命令都是仿照 linux 的,像 ls, mv, cd 等。
- 整个程序的实现用到且只用到了 ANSI C 和其标准库,方便源代码级的跨平台。
fulfs 文件系统功能上包括:
- 对最基本的文件储存的支持。
- 对文件,即能够将文件当成流来读写,也能够对文件进行随机读写。
- 对路径和目录的完整支持。
- 对硬链接的完整支持。
- 对符号链接的支持。
.
├── CMakeLists.txt cmake 文件
├── main.c 程序的主入口
├── test.c 这里是一组测试,在开发时用来测试代码的正确性
├── shell.h 程序提供的模拟 shell 入口。
├── shell.c
├── shell_command.c
├── shell_command.h 程序提供的模拟 shell 提供了一组模仿 linux 命令的命令,在这个模块里实现
├── fs.c
├── fs.h 这里对应设计图的模拟系统调用层。通过这个模块,即可无视文件系统类型操作文件
├── fs_def.h 这里定义了各种具体文件系统的实现和 fs.h 模块的约定接口
├── device_io.c
├── device_io.h 抽象磁盘。这里把一个大文件虚拟成一个磁盘,赋予一个磁盘号,并以扇区为单位进行读写
├── fulfs
│ ├── fulfs.h
│ ├── filesystem.c
│ ├── filesystem.h 对 fulfs 文件系统的操作,如格式化,查看总空闲和剩余空间等。
│ ├── file_dir.c
│ ├── file_dir.h 这里实现了 fulfs 文件系统的普通文件 I/O,目录操作,硬链接以及符号链接
│ ├── base_file.c 在 fulfs 底层,一切都视为以 inode 编号为标志的底层文件
│ ├── base_file.h
│ ├── base_block_file.c 把底层文件成是一个个的盘块组成,提供定位盘块,增加盘块,删除盘块等核心算法。
│ ├── base_block_file.h
│ ├── superblock.c
│ ├── superblock.h superblock 数据结构的操作和封装。
│ ├── inode.c
│ ├── inode.h inode 节点数据结构的操作
│ ├── data_block.c
│ ├── data_block.h 储存数据盘块区的操作,使用成组链接法的核心算法在此
│ ├── block.h 将抽象磁盘看成一个个 block 组成的块,以 block 为单位进行读写
│ └── def.h
├── memory
│ ├── alloc.c
│ └── alloc.h 对动态内存分配的包装
├── datastruct
│ ├── string.c
│ └── string.h 字符串操作的辅助函数
└── utils
├── log.c
├── log.h 日志功能,方便调试
├── math.h 计算相关的小函数
├── path.c
├── path.h 处理路径的辅助函数
├── sys.c 有几个小函数,通过 ANSI C 标准库给原系统的文件加几个操作
├── sys.h
├── testtools.c
└── testtools.h 测试工具
mkdir build
cd build
cmake ..
make之后,目录中生成 main 文件,为可执行文件。
使用示例: ./main create test.fs 32000000 创建一个大小为 32000000 字节的 test.fs 的文件,之后会将此大文件模拟成磁盘供程序使用。
./main format test.fs fulfs 2048 对 test.fs 这个大文件虚拟成的磁盘进行格式化,格式化为 fulfs 文件系统,文件系统盘块大小为 2048.
其中,磁盘的挂载需要写入配置文件 config.txt,如:
A test.fs B test2.fs
这表示,将 test.fs 这个磁盘挂载到盘符 A,将 test2.fs 这个磁盘挂载到盘符 B. 等进入 shell 后,可以使用前面介绍的命令操作文件系统,这些命令都是仿照 linux 命令格式设计的。
./main help 查看使用帮助。
./main enter 进入程序的 shell 以操作挂载的磁盘的文件系统。
这个 shell 模仿 linux 的命令实现了部分命令,包括:
- cd 切换当前目录。
- pwd 输出当前目录。
- ls 列出目录中的文件。
- rmdir 删除空目录。
- mkdir 创建目录。
- ln 创建链接,支持硬链接和符号链接。
- rm 删除文件。
- cp 复制文件。
- mv 移动文件。
- stat 输出文件的信息。
- df 输出挂载的文件系统的信息。
以前总觉得像文件系统实现是遥不可及的事情, 但是直到自己动手实现一个 demo 才发现原来也没想象中的那么难:joy:
这个课程设计断断续续的花了我一个月的时间, 作为我第一个上 5000 行的 C 语言程序,写完之后很累但是也很开心。:smile: