趣谈Linux操作系统
刘超
网易杭州研究院云计算技术部首席架构师
立即订阅
19393 人已学习
课程目录
已完结 72 讲
0/4登录后,你可以任选4讲全文学习。
入门准备篇 (3讲)
开篇词 | 为什么要学习Linux操作系统?
免费
01 | 入学测验:你究竟对Linux操作系统了解多少?
02 | 学习路径:爬过这六个陡坡,你就能对Linux了如指掌
核心原理篇:第一部分 Linux操作系统综述 (3讲)
03 | 你可以把Linux内核当成一家软件外包公司的老板
04 | 快速上手几个Linux命令:每家公司都有自己的黑话
05 | 学会几个系统调用:咱们公司能接哪些类型的项目?
核心原理篇:第二部分 系统初始化 (4讲)
06 | x86架构:有了开放的架构,才能打造开放的营商环境
07 | 从BIOS到bootloader:创业伊始,有活儿老板自己上
08 | 内核初始化:生意做大了就得成立公司
09 | 系统调用:公司成立好了就要开始接项目
核心原理篇:第三部分 进程管理 (10讲)
10 | 进程:公司接这么多项目,如何管?
11 | 线程:如何让复杂的项目并行执行?
12 | 进程数据结构(上):项目多了就需要项目管理系统
13 | 进程数据结构(中):项目多了就需要项目管理系统
14 | 进程数据结构(下):项目多了就需要项目管理系统
15 | 调度(上):如何制定项目管理流程?
16 | 调度(中):主动调度是如何发生的?
17 | 调度(下):抢占式调度是如何发生的?
18 | 进程的创建:如何发起一个新项目?
19 | 线程的创建:如何执行一个新子项目?
核心原理篇:第四部分 内存管理 (7讲)
20 | 内存管理(上):为客户保密,规划进程内存空间布局
21 | 内存管理(下):为客户保密,项目组独享会议室封闭开发
22 | 进程空间管理:项目组还可以自行布置会议室
23 | 物理内存管理(上):会议室管理员如何分配会议室?
24 | 物理内存管理(下):会议室管理员如何分配会议室?
25 | 用户态内存映射:如何找到正确的会议室?
26 | 内核态内存映射:如何找到正确的会议室?
核心原理篇:第五部分 文件系统 (4讲)
27 | 文件系统:项目成果要归档,我们就需要档案库
28 | 硬盘文件系统:如何最合理地组织档案库的文档?
29 | 虚拟文件系统:文件多了就需要档案管理系统
30 | 文件缓存:常用文档应该放在触手可得的地方
核心原理篇:第六部分 输入输出系统 (5讲)
31 | 输入与输出:如何建立售前售后生态体系?
32 | 字符设备(上):如何建立直销模式?
33 | 字符设备(下):如何建立直销模式?
34 | 块设备(上):如何建立代理商销售模式?
35 | 块设备(下):如何建立代理商销售模式?
核心原理篇:第七部分 进程间通信 (7讲)
36 | 进程间通信:遇到大项目需要项目组之间的合作才行
37 | 信号(上):项目组A完成了,如何及时通知项目组B?
38 | 信号(下):项目组A完成了,如何及时通知项目组B?
39 | 管道:项目组A完成了,如何交接给项目组B?
40 | IPC(上):不同项目组之间抢资源,如何协调?
41 | IPC(中):不同项目组之间抢资源,如何协调?
42 | IPC(下):不同项目组之间抢资源,如何协调?
核心原理篇:第八部分 网络系统 (7讲)
43 预习 | Socket通信之网络协议基本原理
43 | Socket通信:遇上特大项目,要学会和其他公司合作
44 | Socket内核数据结构:如何成立特大项目合作部?
45 | 发送网络包(上):如何表达我们想让合作伙伴做什么?
46 | 发送网络包(下):如何表达我们想让合作伙伴做什么?
47 | 接收网络包(上):如何搞明白合作伙伴让我们做什么?
48 | 接收网络包(下):如何搞明白合作伙伴让我们做什么?
核心原理篇:第九部分 虚拟化 (7讲)
49 | 虚拟机:如何成立子公司,让公司变集团?
50 | 计算虚拟化之CPU(上):如何复用集团的人力资源?
51 | 计算虚拟化之CPU(下):如何复用集团的人力资源?
52 | 计算虚拟化之内存:如何建立独立的办公室?
53 | 存储虚拟化(上):如何建立自己保管的单独档案库?
54 | 存储虚拟化(下):如何建立自己保管的单独档案库?
55 | 网络虚拟化:如何成立独立的合作部?
核心原理篇:第十部分 容器化 (4讲)
56 | 容器:大公司为保持创新,鼓励内部创业
57 | Namespace技术:内部创业公司应该独立运营
58 | CGroup技术:内部创业公司应该独立核算成本
59 | 数据中心操作系统:上市敲钟
实战串讲篇 (9讲)
60 | 搭建操作系统实验环境(上):授人以鱼不如授人以渔
61 | 搭建操作系统实验环境(下):授人以鱼不如授人以渔
62 | 知识串讲:用一个创业故事串起操作系统原理(一)
63 | 知识串讲:用一个创业故事串起操作系统原理(二)
64 | 知识串讲:用一个创业故事串起操作系统原理(三)
65 | 知识串讲:用一个创业故事串起操作系统原理(四)
66 | 知识串讲:用一个创业故事串起操作系统原理(五)
67 | 期末测试:这些操作系统问题,你真的掌握了吗?
结束语 | 永远别轻视任何技术,也永远别轻视自己
免费
专栏加餐 (2讲)
学习攻略(一):学好操作系统,需要掌握哪些前置知识?
“趣谈Linux操作系统”食用指南
免费
趣谈Linux操作系统
登录|注册

29 | 虚拟文件系统:文件多了就需要档案管理系统

刘超 2019-06-03
上一节,咱们的图书馆书架,也就是硬盘上的文件系统格式都搭建好了,现在我们还需要一个图书管理与借阅系统,也就是文件管理模块,不然我们怎么知道书都借给谁了呢?
进程要想往文件系统里面读写数据,需要很多层的组件一起合作。具体是怎么合作的呢?我们一起来看一看。
在应用层,进程在进行文件读写操作时,可通过系统调用如 sys_open、sys_read、sys_write 等。
在内核,每个进程都需要为打开的文件,维护一定的数据结构。
在内核,整个系统打开的文件,也需要维护一定的数据结构。
Linux 可以支持多达数十种不同的文件系统。它们的实现各不相同,因此 Linux 内核向用户空间提供了虚拟文件系统这个统一的接口,来对文件系统进行操作。它提供了常见的文件系统对象模型,例如 inode、directory entry、mount 等,以及操作这些对象的方法,例如 inode operations、directory operations、file operations 等。
然后就是对接的是真正的文件系统,例如我们上节讲的 ext4 文件系统。
为了读写 ext4 文件系统,要通过块设备 I/O 层,也即 BIO 层。这是文件系统层和块设备驱动的接口。
为了加快块设备的读写效率,我们还有一个缓存层。
最下层是块设备驱动程序。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《趣谈Linux操作系统》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(19)

  • 烈日融雪
    结合《Linux内核设计与实现》这本书 进入状态更快

    作者回复: 赞

    2019-06-05
    6
  • why
    - 多层组件统一完成进行读写文件的任务
        - 系统调用 sys_open, sys_read 等
        - 进程维护打开的文件数据结构, 系统维护所有打开的文件数据结构
        - Linux 提供统一的虚拟文件系统接口; 例如 inode, directory entry, mount, 以及对应操作 inode operations等, 因此可以同时支持数十种不同的文件系统
        - vfs 通过设备 I/O 层在通过块设备驱动程序访问硬盘文件系统
        - 通过缓存层加快块设备读写
    - 通过解析系统调用了解内核架构
    - 挂载文件系统 mount
        - 注册文件系统 register_filesystem 后才能挂载
        - 调用链 mount->do_mount->do_new_mount→vfs_kern_mount
        - 首先创建 struct mount
            - 其中 mnt_parent 指向父 fs 的 mount; mnt_parentpoint 指向父 fs 的 dentry
            - 用 dentry 表示目录, 并和目录的 inode 关联
            - mnt_root 指向当前 fs 根目录的 dentry; 还有 vfsmount 指向挂载树 root 和超级块
        - 调用 mount_fs 进行挂载
            - 调用 ext4_fs_type→mount(ext4_mount), 读取超级块到内存
            - 文件和文件夹都有一个 dentry, 用于与 inode 关联, 每个挂载的文件系统都由一个 mount 描述; 每个打开的文件都由 file 结构描述, 其指向 dentry 和 mount.
            - 二层文件系统根目录有两个 dentry, 一个表示挂载点, 另一个是上层 fs 的目录.
    - 打开文件 sys_open
        - 先获取一个未使用的 fd, 其中 task_struct.files.fd_array[] 中每一项指向打开文件的 struct file, 其中 fd 作为下标. 默认 0→stdin, 1→stdout, 2→stderr
        - 调用 do_sys_open->do_flip_open
            - 先初始化 nameidata, 解析文件路径名; 接着调用 path_openat
                - 生成 struct file 结构; 初始化 nameidata, 准备查找
                - link_path_walk 根据路径名逐层查找
                - do_last 获取文件 inode, 初始化 file
            - 查找路径最后一部分对应的 dentry
                - Linux 通过目录项高速缓存 dentry cache(dentry) 提高效率. 由两个数据结构组成
                    - 哈希表: dentry_hashtable; 引用变为 0 后加入 lru 链表; dentry 没找到则从 slub 分配; 无法分配则从 lru 中获取; 文件删除释放 dentry;
                    - 未使用的 dentry lru 链表; 再次被引用返回哈希表; dentry 过期返回给 slub 分配器
                - do_last 先从缓存查找 dentry, 若没找到在从文件系统中找并创建 dentry, 再赋给 nameidata 的 path.dentry; 最后调用 vfs_open 真正打开文件
                - vfs_open 会调用 f_op->open 即 ext4_file_open, 还将文件信息存入 struct file 中.
            - 许多结构体中都有自己对应的 operation 结构, 方便调用对应的函数进行处理
    2019-06-05
    3
  • Leon📷
    文章的核心就是把磁盘文件数据映射到进程中,可以把在磁盘的文件组织看成一种协议,内存中进程中的文件组织形式看成另外一种协议,内核就是这两个协议的中转proxy,带着这个主线看文章思路要明朗一些
      inode和dentry在一个文件系统挂载的时候怎么初始化和做好映射关系,这个是难点,我一开始也看懵逼了,后来一想,根文件系统不是挂载了各种磁盘分区的文件系统么,这个老师如果结合centos的xfs根文件系统下,可以挂载ext4的文件系统,并且用一个磁盘分区演示挂载,然后分析,可能大家更好理解,毕竟平时大家都是一个文件系统格式走到黑,个人建议这种复杂逻辑关系比如那个挂载图可以拍个动态图和视频,发个链接让大家去看看,
      

    作者回复: 赞,这个思路好啊

    2019-06-04
    3
  • Guarantee
    老师,您专栏中的图,用的是什么软件,还是就是PS做的图吗?

    作者回复: draw.io

    2019-06-16
    2
  • oldman
    想问问老师,怎么才能学好C语言

    作者回复: 看书,写代码

    2019-07-20
    1
  • Leon📷
    我再补充总结一下
    第一 文章讲的是格式化一个磁盘并且mount到系统根目录
    第二 进程创建过程中跟文件的交互过程,包括打开,创建,当然修改删除老师没讲
    进城文件系统这个我有点疑惑之前老师讲进程task struct有提过,希望老师指点指点
    大家可以自己格式化一个盘ext4,然后strace mount /dev/sdc /test_flash > mntout 2>&1
    我追踪的关于mount的如下
    execve("/bin/mount", ["mount", "/dev/sdc", "/test_flash"], [/* 26 vars */]) = 0
    open("/lib64/libmount.so.1", O_RDONLY|O_CLOEXEC) = 3
    lstat("/run/mount/utab", 0x7ffebb0a8130) = -1 ENOENT (No such file or directory)
    mkdir("/run/mount", 0755) = -1 EEXIST (File exists)
    stat("/run/mount/utab", 0x7ffebb0a8020) = -1 ENOENT (No such file or directory)
    stat("/run/mount", {st_mode=S_IFDIR|0755, st_size=40, ...}) = 0
    access("/run/mount", R_OK|W_OK) = 0
    stat("/sbin/mount.ext4", 0x7ffebb0a6fc0) = -1 ENOENT (No such file or directory)
    stat("/sbin/fs.d/mount.ext4", 0x7ffebb0a6fc0) = -1 ENOENT (No such file or directory)
    stat("/sbin/fs/mount.ext4", 0x7ffebb0a6fc0) = -1 ENOENT (No such file or directory)
    mount("/dev/sdc", "/test_flash", "ext4", MS_MGC_VAL, NULL) = 0
    2019-06-04
    1
  • 陈志恒
    虚拟文件系统其实就是文件系统的数据结构,所以各个数据结构之间的关系要明白,作者在最后已经画出来了!背了它!
    2019-11-25
  • 深寒丶
    老师,你说dentry最重要的作用是指向inode,但是 struct file不是已经指向inode了么
    2019-11-13
  • zhj
    在vfs_kern_mount函数中
    mnt->mnt.mnt_root = root;
    mnt->mnt.mnt_sb = root->d_sb;
    mnt->mnt_mountpoint = mnt->mnt.mnt_root;
    mnt->mnt_parent = mnt;

    这不是说明新分配的mount的挂载点就是vfsmount中的mnt_root
    mnt_parent 就是新分配的mount
    和上文讲到的二者dentry不一致 且 mount的父mount说的不一致
    2019-10-11
  • williamcai
    老师,你好,在dcache中没有找到文件,就会创建一个,这个新创建的文件要不要放入dcache中?
    2019-10-08
  • thomas
    老师,我的理解第一张图中的page cache,应该是buffer吧,而page cache是在VFS这一层
    2019-09-23
  • 计算机班陈公子
    有一点疑惑的就是,是不是一个进程打开一个文件会新建两个struct,一个是file struct他会放进files_struct数组里面,这个file stuct里面拥有inode信息。然后还会新建一个dentry struct,里面也有inode的信息?我看专栏中说这两个struct都是在文件打开后新建的,那这两个作用是否重复?还是说因为dentry还保留了mount的信息?
    2019-09-13
  • 莫名
    `inode 结构就表示硬盘上的 inode,包括块设备号等。` 这个说法不太准确。inode结构体是磁盘文件inode的内存表示,磁盘文件的inode不包含引用计数之类的东西,被读取至内存,使用inode结构体表示。

    作者回复: inode结构就是用来“表示”硬盘上的inode。inode结构体是磁盘文件inode的内存表示,我也是这个意思的

    2019-08-22
  • Geek_54edc1
    如何维护跨文件系统的文件夹和文件的关系:通过dentry在操作系统层面来维护,dentry和inode关联,而且dentry里有parent、child、subdirs这些成员,正好对应文件夹和文件之间的关系

    作者回复: 在内存里面,也有superblock的,会关联dentry

    2019-06-20
  • Geek_54edc1
    老师您好,请教一个问题:lookup_open创建新的dentry后,会把新的dentry加到dentry cache里吗?

    作者回复: 会的

    2019-06-20
  • Spring
    从文章可以看出,父文件系统的挂载点其实就是子文件系统挂载的地方,比如文章中的A文件系统挂载在根文件系统的home目录下,那home是根文件系统的一个挂载点。
    另外,我有一个疑问:data是一个文件,而dentry是一个目录,为什么data文件struct file的dentry指向一个叫data的dentry呢?明明没有data目录呀?

    作者回复: dentry不仅仅表示目录,也可以表示文件

    2019-06-11
  • 刘強
    老师,实在是不理解home目录为什么是根文件系统的挂载点,难道不是那个“/”吗?我一直理解的挂载点就是挂载文件系统的那个目录,希望老师抽个时间,指点一下挂载目录和挂载点的区别,看了一天了,谢谢。

    作者回复: home是在根文件系统上的一个挂载点

    2019-06-03
  • Sharry
    老师的挂载文件系统个人感觉没有错, 我的理解如下

    - 第一层
      - mount: 根文件系统描述
      - dentry: 根文件系统路径
      - file: 根文件系统对应的文件
        - vfsmount: 指向该文件的文件系统
        - dentry: 指向该文件的路径
    - 第二层
      - mount: 文件系统 A 的描述
      - dentry: 文件系统 A 的根路径
      - file: 文件系统 A 的目录文件
    - 第三层
      - mount: 文件系统 B 的描述
      - dentry: 文件系统 B 的根路径
      - file: 文件系统 B 的目录文件
    - 第四层
      - dentry: 文件系统 B 中 world 文件夹路径
      - file: 文件系统 B 中的文件
    - 第五层
      - dentry: 文件系统 B 中 world 文件夹下的文件路径
      - file: 文件系统 B 中 world 文件夹下的文件
    2019-06-03
  • 安排
    老师,能否讲一下读写裸设备和读写设备上的文件的细节方面的区别

    作者回复: 裸设备的话,很难准确辨别文件吧

    2019-06-03
    1
收起评论
19
返回
顶部