# 虚拟文件系统

​		虚拟文件系统VFS是对各类文件系统操作的统一抽象，向上层提供统一一致的接口，便于系统各模块之间降低耦合性，增强可维护性。对一个虚拟文件系统而言，它认为自己是根文件系统，整个可以挂在到VFSM的某个结点上作为子树存在。

​		VFS提供了一组纯虚函数，要求派生类进行实现，派生类可以各自以不同方式实现同样的功能暴露给上层，此外通过文件系统的名称也可以向下进行转化，从而使用派生类的指针进行一些文件系统特有的操作。

​		VFS的设计理念是，VFS作为接口向上提供基本的操作功能，具体实现由VFS派生类内部完成。例如移动一个文件，那么就要求在这个文件系统内部完成，外部不关心是用怎样的机制移动的。而如果需要跨文件系统移动或复制文件，则需要VFSM的介入，帮助进行数据拷贝。

###### VirtualFileSystem的主要成员函数如下：

* FindFile：根据给定目录查找某个文件
* GetAllFileIn：获取某目录下的所有文件名称
* CreateDirectory：创建文件夹
* CreateFile：创建文件
* Move：移动文件
* Copy：拷贝文件
* Delete：删除文件
* GetNextFile：获取给定文件的下一个文件
* Open：打开一个文件
* Close：关闭文件结点
* FileSystemName：获取文件系统名称
* ……



# 文件结点

​		文件结点一方面是与VFS一样性质地作为基类存在，每个文件系统都应该派生自己的文件结点类。此外，文件结点还作为VFSM对全局目录树管理时的管理单位，每一文件结点代表着目录树上的一个结点。这个结点可以是某个具体文件系统的结点，如FAT32文件结点；也可以是虚拟的文件结点，如根节点、设备文件结点等；也可以是虚拟文件系统的根节点代表。也就是说，文件结点管理着某个文件。

​			文件结点提供了一部分文件操作共性的接口，例如读写文件数据、获取文件信息、获取文件路径等。

##### FileNode的主要成员和说明如下：

###### 公开内部结构

* 属性枚举：用于标识与这个文件相关的属性
  * A_Dir：当前结点是一个目录
  * A_Root：当前结点时VFSM的根结点
  * A_VFS：当前结点时VFS的挂载点，是VFS子树的根节点，这棵子树里的所有结点都拥有F_BelongVFS标志，且归当前VFS管理
  * A_Device：当前结点是一个设备
* 状态枚举：用于标识与这个对象相关的属性，与属性枚举的区别在于一个是针对”文件“的，这个是关于”对象“的
  * F_OutsideName：名称来源于外部，不需要主动释放
  * F_BelongVFS：该结点处于某个VFS子树内部
  * F_Managed：该结点是在VFSM管理的全局目录树上的
  * F_Base：该节点是由基类直接创建的
  * F_AutoClose：该结点的引用计数达到0后自动关闭

###### 保护内部变量

* VirtualFileSystem *Vfs：结点所属的虚拟文件系统
* char *Name：文件名称
* Uint64 Attributes：文件属性
* Uint64 Flags：对象特性标志位
* FileNode *fa：父文件结点
* FileNode *pre：前一个兄弟文件结点
* FileNode *nxt：后一个兄弟文件结点
* FileNode *child：第一个孩子文件结点
* Uint64 FileSize：文件大小
* Sint32 RefCount：引用该FileNode的计数

###### 主要成员函数

* SetFileName：设置文件名称，如设置了外部标记flag，则内部的文件名指针直接指向传入参数，否则会对传入参数进行拷贝。
* SetFa：设置文件的父结点，首先取消和原来的父结点的关系，然后建立新的关系
* GetPath_Measure：获取完整的路径字符串的估计部分
* GetPath_Copy：获取完整的路径字符串的拷贝部分
* GetPath：：获取完整的路径字符串（模板参数0表示以VFSM为根，1表示以VFS为根）
* Read：从pos读取size字节到dst
* Write：向pos写入size字节从src
* Ref：增加一次引用
* Unref：解除一次引用，如果由F_AutoClose，则会在引用计数达到0时自动Close
* ……



# 虚拟文件系统管理器

​		虚拟文件系统管理器VFSM维护全局的目录树结构，对于所有的外部请求，都经过VFSM与特定的VFS进行交互。VFSM会将全局路径转化为VFS使用的局部绝对路径，转发给VFS处理。

​		VFSM的设计理念为区分VFS与使用者的接口，它将各个VFS通过挂载到特定结点的方式有机统一起来。包括设备文件、链接等全部放在目录树上，在VFSM的统一管理之下。VFSM的接口与VFS的接口非常相似，不同的是，VFSM是外部访问文件系统的接口，VFS的接口仅供VFSM使用。

​		我们将VFSM设计成管理所有打开的FileNode，这些FileNode组成一棵树，如果一个FileNode存在，那么它的父节点也要求存在，这样我们就不必再结点内部存储完整的路径信息，而可以通过父子关系得到。

##### VirtualFileSystemManager的主要成员和说明如下：

###### 保护内部变量

* FileNode *root：虚拟的FileNode，表示全局的根目录

###### 主要成员函数

* AddNewNode：以fa为父结点添加一个新的文件结点
* AddFileInVFS：在VFS中查找p的名称为name的子节点并添加到目录树上
* FindChildName：通过name查找p的子节点
* FindRecursive：递归地查找并打开某文件结点，如果路径中有未添加到全局目录树的则会添加
* FindPathOfVFS：找到路径所属的VFS并顺便返回它在VFS中的路径指针
* IsAbsolutePath：判断一个路径是否是绝对路径
* NormalizePath：将一个路径规范化，即去除多余的空节、.、..等，当path时相对路径时，需要传入基准路径base
* FindFile：查找文件结点
* GetAllFileIn：获取某个目录下的子文件，result为返回的文件名指针数组，需要用户自己释放字符串，其大小为bufferSize，函数调用的返回值为实际获得的个数，如果达到buffer上限，可以利用skipCnt参数重新读取并跳过一定数量的结果，如此反复
* CreateDirectory：创建文件夹
* CreateFile：创建文件
* Move：移动文件
* Copy：拷贝文件
* Delete：删除文件
* LoadVFS：装载虚拟文件系统到某个路径下，类似于mount
* Open：打开某个路径的文件结点
* Close：关闭某个文件结点
* ……





-----------------------

By：qianpinyi

2022.06.05