前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >OpenHarmony 内核源码分析(VFS篇) | 文件系统和谐共处的基础

OpenHarmony 内核源码分析(VFS篇) | 文件系统和谐共处的基础

原创
作者头像
小帅聊鸿蒙
发布于 2025-03-28 12:56:04
发布于 2025-03-28 12:56:04
3800
代码可运行
举报
文章被收录于专栏:鸿蒙开发笔记鸿蒙开发笔记
运行总次数:0
代码可运行

基本概念 | 官方定义

VFS(Virtual File System)是文件系统的虚拟层,它不是一个实际的文件系统,而是一个异构文件系统之上的软件粘合层,为用户提供统一的类Unix文件操作接口。由于不同类型的文件系统接口不统一,若系统中有多个文件系统类型,访问不同的文件系统就需要使用不同的非标准接口。而通过在系统中添加VFS层,提供统一的抽象接口,屏蔽了底层异构类型的文件系统的差异,使得访问文件系统的系统调用不用关心底层的存储介质和文件系统类型,提高开发效率。

OpenHarmony内核中,VFS框架是通过在内存中的树结构来实现的,树的每个结点都是一个Vnode结构体,父子结点的关系以PathCache结构体保存。VFS最主要的两个功能是:

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

VFS层具体实现包括四个方面:

  • 通过三大函数指针操作接口,实现对不同文件系统类型调用不同接口实现标准接口功能;
  • 通过VnodePathCache机制,提升路径搜索以及文件访问的性能;
  • 通过挂载点管理进行分区管理;
  • 通过FD管理进行进程间FD隔离等。

三大操作接口

VFS层通过函数指针的形式,将统一调用按照不同的文件系统类型,分发到不同文件系统中进行底层操作。各文件系统的各自实现一套Vnode操作(VnodeOps)、挂载点操作(MountOps)以及文件操作接口(file_operations_vfs),并以函数指针结构体的形式存储于对应Vnode、挂载点、File结构体中,实现VFS层对下访问。这三个接口分别为:

VnodeOps | 操作 Vnode 节点
代码语言:c
代码运行次数:0
运行
AI代码解释
复制
struct VnodeOps {
    int (*Create)(struct Vnode *parent, const char *name, int mode, struct Vnode **vnode);//创建节点
    int (*Lookup)(struct Vnode *parent, const char *name, int len, struct Vnode **vnode);//查询节点
    //Lookup向底层文件系统查找获取inode信息
    int (*Open)(struct Vnode *vnode, int fd, int mode, int flags);//打开节点
    int (*Close)(struct Vnode *vnode);//关闭节点
    int (*Reclaim)(struct Vnode *vnode);//回收节点
    int (*Unlink)(struct Vnode *parent, struct Vnode *vnode, const char *fileName);//取消硬链接
    int (*Rmdir)(struct Vnode *parent, struct Vnode *vnode, const char *dirName);//删除目录节点
    int (*Mkdir)(struct Vnode *parent, const char *dirName, mode_t mode, struct Vnode **vnode);//创建目录节点
    /*
    创建一个目录时,实际做了3件事:在其“父目录文件”中增加一个条目;分配一个inode;再分配一个存储块,
    用来保存当前被创建目录包含的文件与子目录。被创建的“目录文件”中自动生成两个子目录的条目,名称分别是:“.”和“..”。
    前者与该目录具有相同的inode号码,因此是该目录的一个“硬链接”。后者的inode号码就是该目录的父目录的inode号码。
    所以,任何一个目录的"硬链接"总数,总是等于它的子目录总数(含隐藏目录)加2。即每个“子目录文件”中的“..”条目,
    加上它自身的“目录文件”中的“.”条目,再加上“父目录文件”中的对应该目录的条目。
    */
    int (*Readdir)(struct Vnode *vnode, struct fs_dirent_s *dir);//读目录节点
    int (*Opendir)(struct Vnode *vnode, struct fs_dirent_s *dir);//打开目录节点
    int (*Rewinddir)(struct Vnode *vnode, struct fs_dirent_s *dir);//定位目录节点
    int (*Closedir)(struct Vnode *vnode, struct fs_dirent_s *dir);//关闭目录节点
    int (*Getattr)(struct Vnode *vnode, struct stat *st);//获取节点属性
    int (*Setattr)(struct Vnode *vnode, struct stat *st);//设置节点属性
    int (*Chattr)(struct Vnode *vnode, struct IATTR *attr);//改变节点属性(change attr)
    int (*Rename)(struct Vnode *src, struct Vnode *dstParent, const char *srcName, const char *dstName);//重命名
    int (*Truncate)(struct Vnode *vnode, off_t len);//缩减或扩展大小
    int (*Truncate64)(struct Vnode *vnode, off64_t len);//缩减或扩展大小
    int (*Fscheck)(struct Vnode *vnode, struct fs_dirent_s *dir);//检查功能
    int (*Link)(struct Vnode *src, struct Vnode *dstParent, struct Vnode **dst, const char *dstName);
    int (*Symlink)(struct Vnode *parentVnode, struct Vnode **newVnode, const char *path, const char *target);
    ssize_t (*Readlink)(struct Vnode *vnode, char *buffer, size_t bufLen);
};

MountOps | 挂载点操作

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
//挂载操作
struct MountOps {
    int (*Mount)(struct Mount *mount, struct Vnode *vnode, const void *data);//挂载
    int (*Unmount)(struct Mount *mount, struct Vnode **blkdriver);//卸载
    int (*Statfs)(struct Mount *mount, struct statfs *sbp);//统计文件系统的信息,如该文件系统类型、总大小、可用大小等信息
};
file_operations_vfs | 文件操作接口
代码语言:c
代码运行次数:0
运行
AI代码解释
复制
struct file_operations_vfs 
{
  int     (*open)(struct file *filep);	//打开文件
  int     (*close)(struct file *filep);	//关闭文件
  ssize_t (*read)(struct file *filep, char *buffer, size_t buflen);	//读文件
  ssize_t (*write)(struct file *filep, const char *buffer, size_t buflen);//写文件
  off_t   (*seek)(struct file *filep, off_t offset, int whence);//寻找,检索 文件
  int     (*ioctl)(struct file *filep, int cmd, unsigned long arg);//对文件的控制命令
  int     (*mmap)(struct file* filep, struct VmMapRegion *region);//内存映射实现<文件/设备 - 线性区的映射>
  /* The two structures need not be common after this point */

#ifndef CONFIG_DISABLE_POLL
  int     (*poll)(struct file *filep, poll_table *fds);	//轮询接口
#endif
  int     (*stat)(struct file *filep, struct stat* st);	//统计接口
  int     (*fallocate)(struct file* filep, int mode, off_t offset, off_t len);
  int     (*fallocate64)(struct file *filep, int mode, off64_t offset, off64_t len);
  int     (*fsync)(struct file *filep);
  ssize_t (*readpage)(struct file *filep, char *buffer, size_t buflen);
  int     (*unlink)(struct Vnode *vnode);
};

PathCache | 路径缓存

PathCache是路径缓存,它通过哈希表存储,利用父节点Vnode的地址和子节点的文件名,可以从PathCache中快速查找到子节点对应的Vnode。当前PageCache仅支持缓存二进制文件,在初次访问文件时通过mmap映射到内存中,下次再访问时,直接从PageCache中读取,可以提升对同一个文件的读写速度。另外基于PageCache可实现以文件为基底的进程间通信。下图展示了文件/目录的查找流程。

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
LIST_HEAD g_pathCacheHashEntrys[LOSCFG_MAX_PATH_CACHE_SIZE];	//路径缓存哈希表项
struct PathCache {//路径缓存
    struct Vnode *parentVnode;    /* vnode points to the cache */	
    struct Vnode *childVnode;     /* vnode the cache points to */
    LIST_ENTRY parentEntry;       /* list entry for cache list in the parent vnode */
    LIST_ENTRY childEntry;        /* list entry for cache list in the child vnode */
    LIST_ENTRY hashEntry;         /* list entry for buckets in the hash table */
    uint8_t nameLen;              /* length of path component */
#ifdef LOSCFG_DEBUG_VERSION
    int hit;                      /* cache hit count*/
#endif
    char name[0];                 /* path component name */
};
//路径缓存初始化
int PathCacheInit(void)
{
    for (int i = 0; i < LOSCFG_MAX_PATH_CACHE_SIZE; i++) {
        LOS_ListInit(&g_pathCacheHashEntrys[i]);
    }
    return LOS_OK;
}

挂载点管理

当前OpenHarmony内核中,对系统中所有挂载点通过链表进行统一管理。挂载点结构体中,记录了该挂载分区内的所有Vnode。当分区卸载时,会释放分区内的所有Vnode。

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
static LIST_HEAD *g_mountList = NULL;//挂载链表,上面挂的是系统所有挂载点
struct Mount {
    LIST_ENTRY mountList;              /* mount list */			 //通过本节点将Mount挂到全局Mount链表上
    const struct MountOps *ops;        /* operations of mount */ //挂载操作函数	
    struct Vnode *vnodeBeCovered;      /* vnode we mounted on */ //要被挂载的节点 即 /bin1/vs/sd 对应的 vnode节点
    struct Vnode *vnodeCovered;        /* syncer vnode */		 //要挂载的节点	即/dev/mmcblk0p0 对应的 vnode节点
    struct Vnode *vnodeDev;            /* dev vnode */
    LIST_HEAD vnodeList;               /* list of vnodes */		//链表表头
    int vnodeSize;                     /* size of vnode list */	//节点数量
    LIST_HEAD activeVnodeList;         /* list of active vnodes */	//激活的节点链表
    int activeVnodeSize;               /* szie of active vnodes list *///激活的节点数量
    void *data;                        /* private data */	//私有数据,可使用这个成员作为一个指向它们自己内部数据的指针
    uint32_t hashseed;                 /* Random seed for vfs hash */ //vfs 哈希随机种子
    unsigned long mountFlags;          /* Flags for mount */	//挂载标签
    char pathName[PATH_MAX];           /* path name of mount point */	//挂载点路径名称  /bin1/vs/sd
    char devName[PATH_MAX];            /* path name of dev point */		//设备名称 /dev/mmcblk0p0
};
//分配一个挂载点
struct Mount* MountAlloc(struct Vnode* vnodeBeCovered, struct MountOps* fsop)
{
    struct Mount* mnt = (struct Mount*)zalloc(sizeof(struct Mount));//申请一个mount结构体内存,小内存分配用 zalloc
    if (mnt == NULL) {
        PRINT_ERR("MountAlloc failed no memory!\n");
        return NULL;
    }

    LOS_ListInit(&mnt->activeVnodeList);//初始化激活索引节点链表
    LOS_ListInit(&mnt->vnodeList);//初始化索引节点链表

    mnt->vnodeBeCovered = vnodeBeCovered;//设备将装载到vnodeBeCovered节点上
    vnodeBeCovered->newMount = mnt;//该节点不再是虚拟节点,而作为 设备结点
#ifdef LOSCFG_DRIVERS_RANDOM	//随机值	驱动模块
    HiRandomHwInit();//随机值初始化
    (VOID)HiRandomHwGetInteger(&mnt->hashseed);//用于生成哈希种子
    HiRandomHwDeinit();//随机值反初始化
#else
    mnt->hashseed = (uint32_t)random(); //随机生成哈子种子
#endif
    return mnt;
}
DD一下:欢迎大家关注公众号<程序猿百晓生>,可以了解到以下知识点。
代码语言:erlang
AI代码解释
复制
`欢迎大家关注公众号<程序猿百晓生>,可以了解到以下知识点。`
1.OpenHarmony开发基础
2.OpenHarmony北向开发环境搭建
3.鸿蒙南向开发环境的搭建
4.鸿蒙生态应用开发白皮书V2.0 & V3.0
5.鸿蒙开发面试真题(含参考答案) 
6.TypeScript入门学习手册
7.OpenHarmony 经典面试题(含参考答案)
8.OpenHarmony设备开发入门【最新版】
9.沉浸式剖析OpenHarmony源代码
10.系统定制指南
11.OpenHarmonyUboot 驱动加载流程
12.OpenHarmony构建系统--GN与子系统、部件、模块详解
13.ohos开机init启动流程
14.鸿蒙版性能优化指南
.......

fd管理 | 两种描述符/句柄的关系

Fd(File Descriptor)是描述一个打开的文件/目录的描述符。当前OpenHarmony内核中,fd总规格为896,分为三种类型:

  • 普通文件描述符,系统总数量为512。
代码语言:c
代码运行次数:0
运行
AI代码解释
复制
    #define CONFIG_NFILE_DESCRIPTORS    512	// 系统文件描述符数量
  • Socket描述符,系统总规格为128。
代码语言:c
代码运行次数:0
运行
AI代码解释
复制
    #define LWIP_CONFIG_NUM_SOCKETS         128	//socket链接数量
    #define CONFIG_NSOCKET_DESCRIPTORS  LWIP_CONFIG_NUM_SOCKETS 
代码语言:c
代码运行次数:0
运行
AI代码解释
复制
    #define CONFIG_NQUEUE_DESCRIPTORS    256

请记住,在OpenHarmony内核中,在不同的层面会有两种文件句柄::

  • 系统文件描述符(sysfd),由内核统一管理,和进程描述符形成映射关系,一个sysfd可以被多个profd映射,也就是说打开一个文件只会占用一个sysfd,但可以占用多个profd,即一个文件被多个进程打开.
  • 进程文件描述符(profd),由进程管理的叫进程文件描述符,内核对不同进程中的fd进行隔离,即进程只能访问本进程的fd.举例说明之间的关系:
代码语言:c
代码运行次数:0
运行
AI代码解释
复制
    文件            sysfd     profd
    吃个桃桃.mp4        10    13(A进程)
    吃个桃桃.mp4        10    3(B进程)
    容嬷嬷被冤枉.txt    12    3(A进程)
    容嬷嬷被冤枉.txt    12    3(C进程)
  • 不同进程的相同fd往往指向不同的文件,但有三个fd例外
    • STDIN_FILENO(fd = 0) 标准输入 接收键盘的输入
    • STDOUT_FILENO(fd = 1) 标准输出 向屏幕输出
    • STDERR_FILENO(fd = 2) 标准错误 向屏幕输出 sysfd和所有的profd的(0,1,2)号都是它们.熟知的 printf 就是向 STDOUT_FILENO中写入数据.
  • 具体涉及结构体
代码语言:c
代码运行次数:0
运行
AI代码解释
复制
    struct file_table_s {//进程fd <--> 系统FD绑定
        intptr_t sysFd; /* system fd associate with the tg_filelist index */
    };//sysFd的默认值是-1
    struct fd_table_s {//进程fd表结构体
        unsigned int max_fds;//进程的文件描述符最多有256个
        struct file_table_s *ft_fds; /* process fd array associate with system fd *///系统分配给进程的FD数组 ,fd 默认是 -1
        fd_set *proc_fds;	//进程fd管理位,用bitmap管理FD使用情况,默认打开了 0,1,2	       (stdin,stdout,stderr)
        fd_set *cloexec_fds;
        sem_t ft_sem; /* manage access to the file table */ //管理对文件表的访问的信号量
    };
    struct files_struct {//进程文件表结构体
        int count;				      //持有的文件数量
        struct fd_table_s *fdt; //持有的文件表
        unsigned int file_lock;	//文件互斥锁
        unsigned int next_fd;	  //下一个fd
    #ifdef VFS_USING_WORKDIR
        spinlock_t workdir_lock;	//工作区目录自旋锁
        char workdir[PATH_MAX];		//工作区路径,最大 256个字符
    #endif
    };
    typedef struct ProcessCB {
    #ifdef LOSCFG_FS_VFS
        struct files_struct *files;        /**< Files held by the process */ //进程所持有的所有文件,注者称之为进程的文件管理器
    #endif	//每个进程都有属于自己的文件管理器,记录对文件的操作. 注意:一个文件可以被多个进程操作
    }

解读

  • 鸿蒙的每个进程ProcessCB都有属于自己的进程的文件描述符files_struct,该进程和文件系统有关的信息都由它表达.
  • 搞清楚 files_struct,fd_table_s,file_table_s三个结构体的关系就明白了进度描述符和系统描述符的关系.
  • fd_table_s是由alloc_fd_table分配的一个结构体数组,用于存放进程的文件描述符
代码语言:c
代码运行次数:0
运行
AI代码解释
复制
        //分配进程文件表,初始化 fd_table_s 结构体中每个数据,包括系统FD(0,1,2)的绑定
        static struct fd_table_s * alloc_fd_table(unsigned int numbers)
        {
          struct fd_table_s *fdt;
          void *data;
          fdt = LOS_MemAlloc(m_aucSysMem0, sizeof(struct fd_table_s));//申请内存
          if (!fdt)
            {
              goto out;
            }
          fdt->max_fds = numbers;//最大数量
          if (!numbers)
            {
              fdt->ft_fds = NULL;
              fdt->proc_fds = NULL;
              return fdt;
            }
          data = LOS_MemAlloc(m_aucSysMem0, numbers * sizeof(struct file_table_s));//这是和系统描述符的绑定
          if (!data)
            {
              goto out_fdt;
            }
          fdt->ft_fds = data;//这其实是个 int[] 数组,
          for (int i = STDERR_FILENO + 1; i < numbers; i++)
            {
                fdt->ft_fds[i].sysFd = -1;//默认的系统描述符都为-1,即还没有和任何系统文件描述符绑定
            }
          data = LOS_MemAlloc(m_aucSysMem0, sizeof(fd_set));//管理FD的 bitmap 
          if (!data)
            {
              goto out_arr;
            }
          (VOID)memset_s(data, sizeof(fd_set), 0, sizeof(fd_set));
          fdt->proc_fds = data;
          alloc_std_fd(fdt);//分配标准的0,1,2系统文件描述符,这样做的结果是任务进程都可以写系统文件(0,1,2)
          (void)sem_init(&fdt->ft_sem, 0, 1);//互斥量初始化
          return fdt;
        out_arr:
          (VOID)LOS_MemFree(m_aucSysMem0, fdt->ft_fds);
        out_fdt:
          (VOID)LOS_MemFree(m_aucSysMem0, fdt);
        out:
          return NULL;
        }
  • file_table_s记录 sysfdprofd的绑定关系.fdt->ft_fds[i].sysFd中的i就是profd

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力;
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识;
  • 想要获取更多完整鸿蒙最新学习知识点,可关注B站:码牛课堂;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
OpenHarmony 内核源码分析(文件句柄篇) | 你为什么叫句柄?
只要写过应用程序代码操作过文件不会陌生这几个函数,文件操作的几个关键步骤嘛,跟把大象装冰箱分几步一样.先得把冰箱门打开,再把大象放进去,再关上冰箱门.其中最重要的一个参数就是fd,应用程序所有对文件的操作都基于它.fd可称为文件描述符,或者叫文件句柄(handle),个人更愿意称后者. 因为更形象,handle英文有手柄的意思,跟开门一样,握住手柄才能开门,手柄是进门关门的抓手.映射到文件系统,fd是应用层出入内核层的抓手.句柄是一个数字编号, open | creat去申请这个编号,内核会创建文件相关的一系列对象,返回编号,后续通过编号就可以操作这些对象.原理就是这么的简单,本篇将从fd入手,跟踪文件操作的整个过程.
小帅聊鸿蒙
2025/03/30
520
OpenHarmony 内核源码分析(索引节点篇) | 谁是文件系统最重要的概念
读懂鸿蒙内核的关键线索是LOS_DL_LIST(双向链表),它是系列篇开篇的内容.
小帅聊鸿蒙
2025/03/27
730
内核文件系统挂载和Open文件
ext4挂载 在linux 5.x的内核中,实际文件系统的挂载采用新的挂载API,引入了struct fs_context用于内部文件系统挂载的信息。 应用端发起mount命令,进入mount系统调用,执行do_mount的函数 // vfs层保留该小节需要的核心字段 struct super_block { // 文件系统类型 struct file_system_type *s_type; // 文件系统super_block的操作函数 const struct super_operations
用户4700054
2022/08/17
1.1K0
谈谈 Linux 文件系统
最近在看一本 Linux 环境编程的书,加上之前工作中接触了一些关于存储的东西,便突然有兴趣整理一下 Linux 是怎么支撑文件系统的。
CS实验室
2021/07/14
4.7K0
谈谈 Linux 文件系统
OpenHarmony 内核源码分析(挂载目录篇) | 为何文件系统需要挂载
关于文件系统的介绍已经写了三篇,但才刚刚开始,其中的 文件系统篇 一定要阅读,用生活中的场景去解释计算机各模块设计的原理和运行机制是整个系列篇最大的特点,计算机文件系统相关概念是非常的多的,若不还原其本质,不跳出这些概念去看问题是很难理解它为什么要弄这么些东东出来让你头大. 反之,如果搞明白了这些概念背后的真相你想忘记它们都很难,问题是经不起追问的, 多追问几个为什么就会离本源越来越近.
小帅聊鸿蒙
2025/03/27
441
OpenHarmony 内核源码分析(挂载目录篇) | 为何文件系统需要挂载
OpenHarmony 内核源码分析(控制台篇)
ConsoleTaskReg将 shellCB和consoleCB捆绑在一块,二者可以相互查找.ShellEntry任务个人更愿意称之为shell的客户端任务,用死循环不断一个字符一个字符的读取用户的输入,为何要单字符 读取可翻看系列篇的Shell编辑篇,简单的说是因为要处理控制字符(如:删除,回车==)
小帅聊鸿蒙
2025/03/31
220
OpenHarmony 内核源码分析(控制台篇)
文件系统专栏 | 之文件系统挂载
ext4文件系统挂载 大家可以使用以下命令挂载一个u盘到 /mnt目录下: mount -t ext4  /dev/sda1 /mnt 其中mount这个应用程序就是使用了mount函数进行系统调用,其系统调用为: SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,   char __user *, type, unsigned long, flags, void __user *, data) {  return
刘盼
2022/08/31
3.4K0
文件系统专栏 | 之文件系统挂载
OpenHarmony 内核源码分析(Shell解析篇) | 应用窥视内核的窗口
系列篇从内核视角用一句话概括shell的底层实现为:两个任务,三个阶段。其本质是独立进程,因而划到进程管理模块。每次创建shell进程都会再创建两个任务。
小帅聊鸿蒙
2025/03/31
350
OpenHarmony 内核源码分析(Shell解析篇) | 应用窥视内核的窗口
OpenHarmony 内核源码分析(根文件系统) | 先挂到/上的文件系统
看网上有很多的文章,但基本全是一大抄,说是内核启动时所mount的第一个文件系统,这话固然是没错, 但想重新定义下这个概念, 所谓 根文件系统 就是先挂到根目录/上的文件系统. 核心是根目录 /. /目录并不必先属于哪个文件系统,否则就是先有蛋还是先有鸡的问题,所以别被蒙圈了,它跟其他文件系统没有任何区别,只是它先来,把坑/给占了,后续来的只能挂到它下面的目录上,最终形成整颗目录树.
小帅聊鸿蒙
2025/03/28
480
OpenHarmony 内核源码分析(根文件系统) | 先挂到/上的文件系统
OpenHarmony 内核源码分析(管道文件篇) | 如何降低数据流动成本
管道符号是两个命令之间的一道竖杠 |,简单而优雅,例如,ls用于显示某个目录中文件,wc用于统计行数.
小帅聊鸿蒙
2025/03/30
371
OpenHarmony 内核源码分析(管道文件篇) | 如何降低数据流动成本
OpenHarmony内核源码分析(进程概念篇) | 进程在管理哪些资源
官方文档最重要的一句话是进程是资源管理单元,注意是管理资源的, 资源是什么? 内存,任务,文件,信号量等等都是资源.故事篇中对进程做了一个形象的比喻(导演),负责节目(任务)的演出,负责协调节目运行时所需的各种资源.让节目能高效顺利的完成.
小帅聊鸿蒙
2025/03/12
780
[apue] 一图读懂 unix 文件句柄及文件共享过程
其中前三项只有文件被打开后才有相应的结构,而后两项只要文件存在就存在了,与文件是否打开没有关系。
海海
2022/08/19
6250
[apue] 一图读懂 unix 文件句柄及文件共享过程
深入理解Linux文件系统之文件系统挂载(下)
注:老内核使用的是vfsmount来描述文件系统的一次挂载,现在内核都使用mount来描述,而vfsmount被内嵌到mount中,主要来描述文件系统的超级块和跟dentry。
用户7244416
2021/08/06
1.9K0
Linux|IO|File IO源码剖析
文件的open、close、read、write是最基本的文件抽象,描述了对于设备的操作。本文将结合用户态的接口以及内核态的实现剖析文件IO。
朝闻君
2021/11/22
3.7K0
Linux|IO|File IO源码剖析
深入理解Linux文件系统之文件系统挂载(上)
我们知道,Linux系统中我们经常将一个块设备上的文件系统挂载到某个目录下才能访问这个文件系统下的文件,但是你有没有思考过:为什么块设备挂载之后才能访问文件?挂载文件系统Linux内核到底为我们做了哪些事情?是否可以不将文件系统挂载到具体的目录下也能访问?下面,本文将详细讲解Linxu系统中,文件系统挂载的奥秘。
用户7244416
2021/08/06
2K0
文件系统专栏 | 之文件系统架构
文件系统层次分析 由上而下主要分为用户层、VFS层、文件系统层、缓存层、块设备层、磁盘驱动层、磁盘物理层 用户层:最上面用户层就是我们日常使用的各种程序,需要的接口主要是文件的创建、删除、打开、关闭、写、读等。 VFS层:我们知道Linux分为用户态和内核态,用户态请求硬件资源需要调用System Call通过内核态去实现。用户的这些文件相关操作都有对应的System Call函数接口,接口调用 VFS对应的函数。 文件系统层:不同的文件系统实现了VFS的这些函数,通过指针注册到VFS里面。所以,用户的操作
刘盼
2022/08/26
2.8K0
文件系统专栏 | 之文件系统架构
从内核看文件描述符传递的实现(基于5.9.9)
前言:文件描述符是内核提供的一个非常有用的技术,典型的在服务器中,主进程负责接收请求,然后把请求传递给子进程处理。本文分析在内核中,文件描述符传递是如何实现的。
theanarkh
2021/07/08
8920
从内核看文件描述符传递的实现(基于5.9.9)
Linux select poll源码剖析
poll机制是所有多路转接的共性;调用控制块(struct poll_wqueues)与监听事件项(struct poll_table_entry)是select()与poll()的共性;事件描述集(fdset)与事件描述符(struct pollfd)是select()与poll()的特性。
233333
2022/05/09
3.2K0
虚拟文件系统
通常我们使用的磁盘和光盘都属于块设备,也就是说它们都是按照 数据块 来进行读写的,可以把磁盘和光盘想象成一个由数据块组成的巨大数组。但这样的读写方式对于人类来说不太友好,所以一般要在磁盘或者光盘上面挂载 文件系统 才能使用。那么什么是 文件系统 呢? 文件系统 是一种存储和组织数据的方法,它使得对其访问和查找变得容易。通过挂载文件系统后,我们可以使用如 /home/docs/test.txt 的方式来访问磁盘中的数据,而不用使用数据块编号来进行访问。
用户7686797
2020/08/25
1.6K0
VFS- 内核是如何抽象文件系统的
UNIX 的哲学之一就是一切皆文件,所以可以看出文件系统在操作系统层面是非常重要的,很多基本单元都是通过文件系统展开的,所以了解文件系统有利于分析整个操作系统的脉络。
Linux阅码场
2019/06/04
1.8K0
VFS- 内核是如何抽象文件系统的
推荐阅读
相关推荐
OpenHarmony 内核源码分析(文件句柄篇) | 你为什么叫句柄?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验