linux内核-虚拟文件系统

前言

学习《深入linux内核架构》的书本阅读。基本是书中知识点的摘抄。

VFS虚拟文件系统

VFS在内核的层次结构图。
VFS在内核的层次结构图

应用目的:为支持本机文件系统,同时允许访问其他操作系统的文件,Linux内核在用户层和文件系统间引入了抽象层,虚拟文件系统(Virtual File System)。

文件系统类型

  1. Disk-based Filesystem
    如EXT2
  2. Virtual Filesystem
    如proc
  3. 网络文件系统
    如NFS

通用文件模型

VFS的解决方案,提供一种结构模型,包含文件系统所应具备的所有组件。此模型,只存在与虚拟中,必须使用各种对象和函数指针与每种文件系统适配。

处理文件时,内核空间用户空间使用的主要对象是不同的。

用户程序:一个文件由一个文件描述符标识,描述符是整数,用作所有有关文件的操作中用作标识文件的参数。文件描述符是在打开文件时由内核分配的,只在一个进程内部有效。(这很重点,同桌还说是否有可能功用一个文件描述符,在这里看起来就不是了)。两个不同的进程可以使用同样的文件描述符,但是二者不能指向同一个文件。基于同一个描述符来共享文件是不可能的(为什么呢?)

内核空间: 内核处理文件的关键是inode。每个文件(和目录)都有且仅有一个对应的inode,其中包含元数据(访问时间,等),和指向文件数据的指针。但inode不包含文件名

inode

先给出inode在内核中的结构体定义。

inode成员分为两类:

  1. 描述文件状态的元数据。如,atime,ctime,mtime
  2. 保存实际文件内容的数据段(或者指向数据的指针)

书中给了一个示例,来阐述利用inodes来构造文件系统的目录层次结构。
(看起来是结合了inode, dentry来完成文件的查找,只是当前还没有介绍dentry的概念)

查找首先,起始于一个inode,表示根目录/。(根目录的inode,对于系统来说是已知的)。根目录是由一个inode表示,其数据段并不包含普通的数据,而是根目录下的各个目录项。

目录项由两个成员组成:

  1. 该目录项的数据所在inode的编号
  2. 文件或者目录的名称

系统中所有的inode都有一个特定的编号,用于唯一标识各个inode。文件名和inode之间的关联就是通过该编号完成的。

/usr/bin/emacs为例,查找过程:
第一步,查找子目录usrinode,这一步会扫描根inode的数据段,直至找到一个名为usr的目录项。
第二步,重复第一步,直至在bin的数据段中查找到emacs的目录项,这时仍旧返回一个inode编号而非目录。(这很奇怪呀,如果最后一项仍旧是目录呢?)
第三步,最后一个inode的文件内容,与前三个inode不同。前三个inode都表示目录,其文件内容是目录项的列表,包括子目录和文件。与emacs文件关联的inode,其数据段存储了文件的内容。

下面,给出一张图片,完整描述上面的故事:
查找/usr/bin/emacs的操作

链接

链接(link)是建立文件系统对象之间的联系。

软连接:
又称符号链接,(可以理解为方向指针,或者是快捷方式),表示文件存在于某一个特定位置。常用的场景,例如若想自己编译的可执行文件能够全局可用,就可以使用:

[root@k8s-master Workspace]# ln -s /root/Workspace/exec /usr/bin/exec
[root@k8s-master /]# exec 
Hello World

本质上,软连接和链接目标没有紧密的耦合,软连接可以认为是一个目录项,除了指向文件名的指针,并不存放其他数据。。目标文件与链接文件均有独立的inode,相应的inode的数据端包含一个字符串,给出了链接目标的路径。目标文件删除,符号链接仍旧可以保持。

1. 软连接, inode值不同
$ ln -s [root@192 shell]# ln -s /root/Code/homework/shell/exec /usr/bin/exec
[root@192 shell]# ls -i exec
104907757 exec
[root@192 shell]# ls -i /usr/bin/exec
5039594 /usr/bin/exec

2. 删除软连接
$ rm -f /usr/bin/exec

硬链接:
硬链接建立时,创建的目录项使用了一个现存的inode编号,即自身。

3. 硬连接,inode值相同
[root@192 shell]# ln /root/Code/homework/shell/exec /usr/bin/exec
[root@192 shell]# ls -i exec 
104907757 exec
[root@192 shell]# ls -i /usr/bin/exec 
104907757 /usr/bin/exec

4. 删除硬连接
rm -f /usr/bin/exec

知识点2:
假定硬连接(B)与原始文件(A)共同享用同一个inode。一个用户若想要删除文件A,通常会**销毁相关的inode和其数据段,以便释放存储空间以便后续使用。**但将会导致,文件B无法访问。

为此,会在inode中加入计数器,每对文件创建一个硬连接时,都会将计数器加1.如果其中一个硬连接或者原始文件被删除,那么计数器将减一,计数器归0时,才确认inode不会再被使用,可以从文件中删除。

编程接口

文件被使用前,必须使用openopenat系统调用。在成功打开文件之后,内核向用户层返回一个非负整数。(这里赶脚是文件描述符)。分配的文件描述符起始于3。(这是因为0,1,2分别对应着标准输入,标准输出,标准错误流)。

文件被打开后,名称就没有特别大的用处了,现在仅有文件描述符唯一标识。所有其他的库函数,都需要传递一个文件描述符号作为一个参数。由于多个命名空间和容器的引入(影响啥了呢),具有相同数值的多个文件描述符可以共存于内核中,对文件的唯一标识由一个特殊的数据结构(struct file)提供

将文件作为通用接口

使用文件作为其主要通信手段的一部分内核子系统:

  1. 字符和块设备
  2. 进程间的管道
  3. 用于所有网络协议的套接字(怪不得说,套接字是一个文件呢)
  4. 用于交互式输入和输出的终端
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值