前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DragonOS虚拟文件系统概述

DragonOS虚拟文件系统概述

作者头像
灯珑LoGin
发布2022-10-31 15:28:43
4800
发布2022-10-31 15:28:43
举报
文章被收录于专栏:龙进的专栏

本文已基于GPLv2协议发布在https://docs.dragonos.org/zh_CN/latest/kernel/filesystem/vfs/overview.html

简介

  DragonOS的虚拟文件系统是内核中的一层适配器,为用户程序(或者是系统程序)提供了通用的文件系统接口。同时对内核中的不同文件系统提供了统一的抽象。各种具体的文件系统可以挂载到VFS的框架之中。

  与VFS相关的系统调用有open(), read(), write(), create()等。

dentry对象

  dentry的全称为directory entry,是VFS中对于目录项的一种抽象数据结构。当读取具体文件系统时,将会由创建dentry对象。dentry对象中包含了指向inode的指针。

  dentry对象为真实文件系统上的目录结构建立了缓存,一旦内存中存在对应路径的dentry对象,我们就能直接获取其中的信息,而不需要进行费时的磁盘操作。请注意,dentry只是为提高文件系统性能而创建的一个缓存,它并不会被写入到磁盘之中。

inode对象

  inode的全称叫做index node,即索引节点。一般来说,每个dentry都应当包含指向其inode的指针。inode是VFS提供的对文件对象的抽象。inode中的信息是从具体文件系统中读取而来,也可以被刷回具体的文件系统之中。并且,一个inode也可以被多个dentry所引用。

  要查找某个路径下的inode,我们需要调用父目录的inode的lookup()方法。请注意,该方法与具体文件系统有关,需要在具体文件系统之中实现。

文件描述符对象

  当一个进程试图通过VFS打开某个文件时,我们需要为这个进程创建文件描述符对象。每个文件对象都会绑定文件的dentry和文件操作方法结构体,还有文件对象的私有信息。

  文件描述符对象中还包含了诸如权限控制、当前访问位置信息等内容,以便VFS对文件进行操作。

  我们对文件进行操作都会使用到文件描述符,具体来说,就是要调用文件描述符之中的file_ops所包含的各种方法。

注册文件系统到VFS

  如果需要注册或取消注册某个具体文件系统到VFS之中,则需要以下两个接口:

代码语言:javascript
复制
#include<filesystem/VFS/VFS.h>

uint64_t vfs_register_filesystem(struct vfs_filesystem_type_t *fs);
uint64_t vfs_unregister_filesystem(struct vfs_filesystem_type_t *fs);

  这里需要通过struct vfs_filesystem_type_t来描述具体的文件系统。

struct vfs_filesystem_type_t

  这个数据结构描述了具体文件系统的一些信息。当我们挂载具体文件系统的时候,将会调用它的read_superblock方法,以确定要被挂载的文件系统的具体信息。

  该数据结构的定义在kernel/filesystem/VFS/VFS.h中,结构如下:

代码语言:javascript
复制
struct vfs_filesystem_type_t
{
    char *name;
    int fs_flags;
    // 解析文件系统引导扇区的函数,为文件系统创建超级块结构。其中DPTE为磁盘分区表entry(MBR、GPT不同)
    struct vfs_superblock_t *(*read_superblock)(void *DPTE, uint8_t DPT_type, void *buf, int8_t ahci_ctrl_num, int8_t ahci_port_num, int8_t part_num); 
    struct vfs_filesystem_type_t *next;
};

name

  文件系统名称字符串

fs_flags

  文件系统的一些标志位。目前,DragonOS尚未实现相关功能。

read_superblock

  当新的文件系统实例将要被挂载时,将会调用此方法,以读取具体的实例的信息。

next

  指向链表中下一个struct vfs_filesystem_type_t的指针。

超级块(superblock)对象

  一个超级块对象代表了一个被挂载到VFS中的具体文件系统。

struct vfs_superblock_t

  该数据结构为超级块结构体。

  该数据结构定义在kernel/filesystem/VFS/VFS.h中,结构如下:

代码语言:javascript
复制
struct vfs_superblock_t
{
    struct vfs_dir_entry_t *root;
    struct vfs_super_block_operations_t *sb_ops;
    void *private_sb_info;
};

root

  该具体文件系统的根目录的dentry

sb_ops

  该超级块对象的操作方法。

private_sb_info

  超级块的私有信息。包含了具体文件系统的私有的、全局性的信息。

struct vfs_super_block_operations_t

  该数据结构为超级块的操作接口。VFS通过这些接口来操作具体的文件系统的超级块。

  该数据结构定义在kernel/filesystem/VFS/VFS.h中,结构如下:

代码语言:javascript
复制
struct vfs_super_block_operations_t
{
    void (*write_superblock)(struct vfs_superblock_t *sb);
    void (*put_superblock)(struct vfs_superblock_t *sb);
    void (*write_inode)(struct vfs_index_node_t *inode); // 将inode信息写入磁盘
};

write_superblock

  将superblock中的信息写入磁盘

put_superblock

  释放超级块

write_inode

  将inode的信息写入磁盘

索引结点(inode)对象

  每个inode对象代表了具体的文件系统之中的一个对象(目录项)。

struct vfs_index_node_t

  该数据结构为inode对象的数据结构,与文件系统中的具体的文件结点对象具有一对一映射的关系。

  该数据结构定义在kernel/filesystem/VFS/VFS.h中,结构如下:

代码语言:javascript
复制
struct vfs_index_node_t
{
    uint64_t file_size; // 文件大小
    uint64_t blocks;    // 占用的扇区数
    uint64_t attribute;

    struct vfs_superblock_t *sb;
    struct vfs_file_operations_t *file_ops;
    struct vfs_inode_operations_t *inode_ops;

    void *private_inode_info;
};

file_size

  文件的大小。若为文件夹,则该值为文件夹内所有文件的大小总和(估计值)。

blocks

  文件占用的磁盘块数(扇区数)

attribute

  inode的属性。可选值如下:

  • VFS_ATTR_FILE
  • VFS_ATTR_DIR
  • VFS_ATTR_DEVICE

sb

  指向文件系统超级块的指针

file_ops

  当前文件的操作接口

inode_ops

  当前inode的操作接口

private_inode_info

  与具体文件系统相关的inode信息。该部分由具体文件系统实现,包含该inode在具体文件系统之中的特定格式信息。

struct vfs_inode_operations_t

  该接口为inode的操作方法接口,由具体文件系统实现。并与具体文件系统之中的inode相互绑定。

  该接口定义于kernel/filesystem/VFS/VFS.h中,结构如下:

代码语言:javascript
复制
struct vfs_inode_operations_t
{
    long (*create)(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry, int mode);
    struct vfs_dir_entry_t *(*lookup)(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry);
    long (*mkdir)(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode);
    long (*rmdir)(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry);
    long (*rename)(struct vfs_index_node_t *old_inode, struct vfs_dir_entry_t *old_dEntry, struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry);
    long (*getAttr)(struct vfs_dir_entry_t *dEntry, uint64_t *attr);
    long (*setAttr)(struct vfs_dir_entry_t *dEntry, uint64_t *attr);
};

create

  在父节点下,创建一个新的inode,并绑定到dest_dEntry上。

  该函数的应当被sys_open()系统调用在使用了O_CREAT选项打开文件时调用,从而创建一个新的文件。请注意,传递给create()函数的dest_dEntry参数不应包含一个inode,也就是说,inode对象应当被具体文件系统所创建。

lookup

  当VFS需要在父目录中查找一个inode的时候,将会调用lookup方法。被查找的目录项的名称将会通过dest_dEntry传给lookup方法。

  若lookup方法找到对应的目录项,将填充完善dest_dEntry对象。否则,返回NULL。

mkdir

  该函数被mkdir()系统调用所调用,用于在inode下创建子目录,并将子目录的inode绑定到dEntry对象之中。

rmdir

  该函数被rmdir()系统调用所调用,用于删除给定inode下的子目录项。

rename

  该函数被rename系统调用(尚未实现)所调用,用于将给定的目录项重命名。

getAttr

  用来获取目录项的属性。

setAttr

  用来设置目录项的属性

转载请注明来源:https://longjin666.cn/?p=1478

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年7月12日2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
    • dentry对象
      • inode对象
        • 文件描述符对象
        • 注册文件系统到VFS
          • struct vfs_filesystem_type_t
          • 超级块(superblock)对象
            • struct vfs_superblock_t
              • struct vfs_super_block_operations_t
              • 索引结点(inode)对象
                • struct vfs_index_node_t
                  • struct vfs_inode_operations_t
                  相关产品与服务
                  文件存储
                  文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档