VFS

    基本概念

    由于不同类型的文件系统接口不统一,若系统中有多个文件系统类型,访问不同的文件系统就需要使用不同的非标准接口。而通过在系统中添加VFS层,提供统一的抽象接口,屏蔽了底层异构类型的文件系统的差异,使得访问文件系统的系统调用不用关心底层的存储介质和文件系统类型,提高开发效率。VFS和各个具体文件系统的关系如下:

    图 1 VFS和各个文件系统的关系

    OpenHarmony内核中,VFS框架是通过在内存中的树结构来实现的,树的每个结点都是一个inode结构体。设备注册和文件系统挂载后会根据路径在树中生成相应的结点。VFS最主要是两个功能:

    • 查找节点。
    • 统一调用(标准)。

    通过VFS层,可以使用标准的Unix文件操作函数(如open、read、write等)来实现对不同介质上不同文件系统的访问。

    VFS框架内存中的inode树结点有三种类型:

    • 虚拟结点:作为VFS框架的虚拟文件,保持树的连续性,如/usr、/usr/bin。
    • 设备结点:/dev目录下,对应一个设备,如/dev/mmc0blk0。
    • 挂载点:挂载具体文件系统,如/vs/sd、/mnt。

    inode的关键在于u和i_private字段,一个是函数方法结构体的指针,一个是数据指针。

    图 2 文件系统树形结构
    VFS - 图1

    注意事项

    • 目前仅有jffs2文件系统支持完整的权限控制。

    • inode_find()函数调用后会使查找到的inode节点连接数+1,调用完成后需要调用inode_release()使连接数-1,所以一般inode_find()要和inode_release()配套使用。

    • los_vfs_init()只能调用一次,多次调用将会造成文件系统异常。

    • 目前OpenHarmony内核所有的文件系统中的文件名和目录名中只可以出现“-” 与“_”两种特殊字符,使用其他特殊字符可能造成的后果不可预知,请谨慎为之。

    • OpenHarmony内核支持open()+O_DIRECTORY的方法获取目录数据信息。

    • 挂载点必须为空目录,不能重复挂载至同一挂载点或挂载至其他挂载点下的目录或文件,错误挂载可能损坏设备及系统。

    • open打开一个文件时,参数O_RDWR、O_WRONLY、O_RDONLY互斥,只能出现一个,若出现2个或以上作为open的参数,文件读写操作会被拒绝,并返回EACCESS错误码,禁止使用。

    • OpenHarmony内核文件系统在umount操作之前,需确保所有目录及文件全部关闭,否则umount会失败。如果强制umount,可能导致包括但不限于文件系统损坏、设备损坏等问题。

    • SD卡移除前,需确保所有目录及文件全部关闭,并进行umount操作。如果强制拔卡,可能导致包括但不限于SD数据丢失、SD卡损坏等问题。

    开发流程

    推荐驱动开发人员使用VFS框架来注册/卸载设备,应用层使用open()、read()操作设备(字符设备)文件来调用驱动。

    1. 系统调用了los_vfs_init()后,会将”/“作为root_inode。

    2. 在调用时根据路径在树中进行查找,匹配到相应的设备或挂载点。

    3. 通过查找到的结点指针可调用相应的函数。

    文件描述符

    本系统中,进程的文件描述符最多有256个(File和Socket描述符合并统计),系统文件描述符共640个,系统文件描述符规格:

    • File描述符,普通文件描述符,系统总规格为512。

    • Socket描述符,系统总规格为128。

    VFS支持的操作

    open, close, read, write, seek, ioctl, fcntl, mmap, sync, dup, dup2, truncate, opendir, closedir, readdir, readdir, rewinddir, mount, umount, statfs, unlink, remove, mkdir, rmdir, rename, stat, utime, seek64, fallocate, fallocate64, truncate64, chmod, chown。

    编程实例