@IT·互联网鸿蒙(HarmonyOS)开发知识

鸿蒙内核源码分析(索引节点篇) | 谁是文件系统最重要的

2025-06-03  本文已影响0人  迪士尼在逃程序员

读懂鸿蒙内核的关键线索是LOS_DL_LIST(双向链表),它是系列篇开篇的内容.
而读懂文件系统的关键线索是vnode(索引节点),vnode在文件系统中起承上启下的关键点.vnodeBSD的叫法,鸿蒙沿用了BSD的称呼,linux的叫法是inode,关于vnode有翻译成虚拟节点,但系列篇还是统一翻译成索引节点.

什么是 vnode

先看大佬们对其的定义

OpenBSD 定义

A vnode is an object in kernel memory that speaks the UNIX file interface (open, read, write, close, readdir, etc.). Vnodes can represent files, directories, FIFOs, domain sockets, block devices, character devices.

vnode 是内核内存中的一个对象,它使用 UNIX 文件接口(打开、读取、写入、关闭、readdir 等)。 Vnodes 可以代表文件、目录、管道、套接字、块设备、字符设备。

freeBSD 定义

vnode -- internal representation of a file or directory . The vnode is the focus of all file activity in UNIX. A vnode is described by struct vnode. There is a unique vnode allocated for each active file, each current directory, each mounted-on file, text file, and the root.

vnode -- 文件或目录的内部表示. vnode 是 UNIX 中所有文件活动的焦点。 vnode 由 struct vnode 描述。 为每个活动文件、每个当前目录、每个挂载文件、文本文件和根分配了一个唯一的 vnode。

linux 定义

The inode (index node) is a data structure in a Unix-style file system that describes a file-system object such as a file or a directory. Each inode stores the attributes and disk block locations of the object's data.[1] File-system object attributes may include metadata (times of last change, access, modification), as well as owner and permission data.

inode(索引节点)是 Unix 风格的文件系统中的一种数据结构,用于描述文件系统对象,例如文件或目录。 每个 inode 存储对象数据的属性和磁盘块位置。 文件系统对象属性可能包括元数据(上次更改、访问、修改的时间),以及所有者和权限数据。

综上所述,发现木有,这说的可不就是 [v63.xx 鸿蒙内核源码分析(文件系统篇) | 用图书管理说文件系统 ] 中的索引页吗? 没读过的建议先阅读后再继续.对于在硬盘中的vnode,在系统启动后vnode会被加载到内存管理,但因内存问题并不会全部加载.

vnode 长啥样

Vnode 是具体文件或目录在VFS层的抽象封装,它屏蔽了不同文件系统的差异,实现资源的统一管理。Vnode通过哈希以及LRU机制进行管理。当系统启动后,对文件或目录的访问会优先从哈希链表中查找Vnode缓存,若缓存没有命中,则并从对应文件系统中搜索目标文件或目录,创建并缓存对应的Vnode。当Vnode缓存数量达到上限时,将淘汰长时间未访问的Vnode,其中挂载点Vnode与设备节点Vnode不参与淘汰。Vnode节点主要有以下几种类型:

本篇主要围绕 vnode结构体来说,说透说烂这个文件系统最关键的节点.

struct IATTR { //此结构用于记录 vnode 的属性
  /* This structure is used for record vnode attr. */
  unsigned int attr_chg_valid;//节点改变有效性 (CHG_MODE | CHG_UID | ... )
  unsigned int attr_chg_flags;//额外的系统与用户标志(flag),用来保护该文件
  unsigned attr_chg_mode;   //确定了文件的类型,以及它的所有者、它的group、其它用户访问此文件的权限 (S_IWUSR | ...)
  unsigned attr_chg_uid;    //用户ID
  unsigned attr_chg_gid;    //组ID
  unsigned attr_chg_size;   //节点大小
  unsigned attr_chg_atime;  //节点最近访问时间
  unsigned attr_chg_mtime;  //节点对应的文件内容被修改时间
  unsigned attr_chg_ctime;  //节点自身被修改时间
};
// 对IATTR的修改最终将落到 vnode->vop->Chattr(vnode, attr);
enum VnodeType {//节点类型
    VNODE_TYPE_UNKNOWN,       /* unknown type */    //未知类型
    VNODE_TYPE_REG,           /* regular file */    //vnode代表一个正则文件(普通文件)
    VNODE_TYPE_DIR,           /* directory */         //vnode代表一个目录
    VNODE_TYPE_BLK,           /* block device */    //vnode代表一个块设备
    VNODE_TYPE_CHR,           /* char device */     //vnode代表一个字符设备
    VNODE_TYPE_BCHR,          /* block char mix device *///块和字符设备混合
    VNODE_TYPE_FIFO,          /* pipe */            //vnode代表一个管道
    VNODE_TYPE_LNK,           /* link */            //vnode代表一个符号链接
};
struct Vnode {//vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
    enum VnodeType type;                /* vnode type */    //节点类型 (文件|目录|链接...)
    int useCount;                       /* ref count of users *///节点引用(链接)数,即有多少文件名指向这个vnode,即上层理解的硬链接数   
    uint32_t hash;                      /* vnode hash */    //节点哈希值
    uint uid;                           /* uid for dac */   //文件拥有者的User ID
    uint gid;                           /* gid for dac */   //文件的Group ID
    mode_t mode;                        /* mode for dac */  //chmod 文件的读、写、执行权限
    LIST_HEAD parentPathCaches;         /* pathCaches point to parents */   //指向父级路径缓存,上面的都是当了爸爸节点
    LIST_HEAD childPathCaches;          /* pathCaches point to children */  //指向子级路径缓存,上面都是当了别人儿子的节点
    struct Vnode *parent;               /* parent vnode */  //父节点
    struct VnodeOps *vop;               /* vnode operations */  //相当于指定操作Vnode方式 (接口实现|驱动程序)
    struct file_operations_vfs *fop;    /* file operations */   //相当于指定文件系统
    void *data;                         /* private data */      //文件数据block的位置,指向每种具体设备私有的成员,例如 ( drv_data | nfsnode | ....)
    uint32_t flag;                      /* vnode flag */        //节点标签
    LIST_ENTRY hashEntry;               /* list entry for bucket in hash table */ //通过它挂入哈希表 g_vnodeHashEntrys[i], i:[0,g_vnodeHashMask]
    LIST_ENTRY actFreeEntry;            /* vnode active/free list entry */  //通过本节点挂到空闲链表和使用链表上
    struct Mount *originMount;          /* fs info about this vnode */ //自己所在的文件系统挂载信息
    struct Mount *newMount;             /* fs info about who mount on this vnode */ //其他挂载在这个节点上文件系统信息
};

解读

写在最后

上一篇 下一篇

猜你喜欢

热点阅读