Linux 文件描述符 文件表项 i节点结构

Linux的VFS(虚拟文件系统)学习起来很痛苦,看源码不太明智,看完分析完就忘且太浪费时间,懂了后也无法应用在实际场合中。所以这里只是讨论下文件描述符,文件表项(file结构体)和inode,理清实现的思路。

一、概念
首先区分文件描述符和打开的文件。内核维护了三个数据结构,分别是:
进程级的文件描述符表(即每个进程一个);
系统级的打开文件表(即该表在整个内核中只有一个),表项为struct file;
文件系统的 inode 表;

  1. 针对每个进程,内核为其维护一个打开的文件描述符表(open file descriptor table),可将其视为一个矢量,每个描述项占用一项,该表的每一项都记录了单个文件描述符的相关信息。 与每个文件描述符相关联的是:
    1). 文件描述符标志:控制文件描述符的操作的一组标识,目前只定义了一个,即(close-on-exec)。如果某个文件符设置了该标志,fcntl(fd, F_SETFD, 1), 则在该进程调用exec函数之前为exec族函数释放对应的文件描述符。只作用在一个进程中
    2). 指向一个文件表项file结构体的指针

  2. 内核为所有打开文件维持一张系统级别的描述表格(open file description table)。每个文件表项即file结构体保存了一个已打开的文件的所有相关信息:
    1). 文件状态标志:读、写、添写(即O_APPEND)、同步、非阻塞等,作用于全部进程。即任何进程中的所有描述符都可指向同一个文件状态标志。
    2). 文件指针偏移量 (read()和write()修改,以及lseek()修改)
    3). 文件访问模式
    4). 与信号驱动I/O相关的设置
    5). 指向该文件inode表项的指针

  3. 文件都有文件名与数据,这在 Linux 上被分成两个部分:用户数据 (user data) 与元数据 (metadata)。
    用户数据:即文件数据块 (data block),记录文件真实内容;
    元数据:记录文件的附加属性。
    在 Linux 中,元数据中的 inode 号(inode 是文件元数据的一部分但其并不包含文件名,inode 号即索引节点号)才是文件的唯一标识而非文件名。文件名仅是为了方便人们的记忆和使用,系统或程序通过 inode 号寻找正确的文件数据块。

图 1.展示了程序通过文件名获取文件内容的过程。
在这里插入图片描述
因此,每个打开文件(或设备)都有个inode结构。inode中文译名为"索引节点",储存文件的元信息。包括:
1). 文件的字节数
2). 文件拥有者的User ID
3). 文件的Group ID
4). 文件的读、写、执行权限
5). 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。
6). 链接数,即有多少文件名指向这个inode
7). 文件数据block的位置
可以用stat命令,查看某个文件的inode信息。
这些信息是在打开文件时从磁盘上读入内存的,所以所有关于文件的信息都是快速可供使用的。
每一个文件对应一个inode,硬盘上有多少文件,就有多少个inode。

二、图释
注意:Linux没有使用v节点,而是使用了通用的i节点结构,即inode。虽然这两种实现有所不同,但在概念上,v节点和i节点是一样的。两者都指向文件系统所特有的i节点结构。因为图片关系,将图中v节点视为inode。

图1:打开文件的内核数据结构
在这里插入图片描述

图2:两个独立进程各自打开同一个文件
在这里插入图片描述
此图中可以看出,对于同一个文件,打开该文件的每个进程都得到一个文件表项file结构体,但对一个给定的文件只有一个inode表项。
而每个进程都有自己的file结构体的一个理由是:使每个进程都有它自己的对该文件的当前偏移量。

注:文件描述符标志的作用域:只在一个进程中
文件状态标志的作用域:任何进程中的所有描述符都可指向同一个文件状态标志。

图3:执行了dup之后的内核数据结构.JPG在这里插入图片描述
首先了解下dup与dup2。
当调用dup函数时,内核在进程中创建一个新的文件描述符,此描述符是当前可用文件描述符的最小数值,这个文件描述符指向oldfd所拥有的文件表项。

在文件表或者inode中都有索引计数,引用计数为0的时候,即文件引用为0的时候就可以清除文件表项了。

三、问题
1.硬链接与软链接的联系与区别
图示:
在这里插入图片描述
硬链接:一般情况下,文件名和inode号码是"一一对应"关系,每个inode号码对应一个文件名。但是,Unix/Linux系统允许,多个文件名指向同一个inode号码。这意味着,可以用不同的文件名访问同样的内容;对文件内容进行修改,会影响到所有文件名;但是,删除一个文件名,不影响另一个文件名的访问。这种情况就被称为"硬链接"(hard link)。
ln命令可以创建硬链接:ln 源文件 目标文件
运行上面这条命令以后,源文件与目标文件的inode号码相同,都指向同一个inode,inode的链接数成员这时就会增加1。反过来,删除一个文件名,就会使得inode节点中的"链接数"减1。当这个值减到0,表明没有文件名指向这个inode,系统就会回收这个inode号码,以及其所对应block区域。

软链接:文件A和文件B的inode号码虽然不一样,但是文件A的内容是文件B的路径。读取文件A时,系统会自动将访问者导向文件B。因此,无论打开哪一个文件,最终读取的都是文件B。这时,文件A就称为文件B的"软链接"(soft link)或者"符号链接(symbolic link)。
这意味着,文件A依赖于文件B而存在,如果删除了文件B,打开文件A就会报错:“No such file or directory”。
这是软链接与硬链接最大的不同:文件A指向文件B的文件名,而不是文件B的inode号码,文件B的inode"链接数"不会因此发生变化
ln -s命令可以创建软链接。ln -s 源文文件或目录 目标文件或目录

2.inode不含文件名!
文件名仅是为了方便人们的记忆和使用,系统或程序通过 inode 号寻找正确的文件数据块。
所以打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名。因此,通常来说,系统无法从inode号码得知文件名。
这一点使得软件更新变得简单,可以在不关闭软件的情况下进行更新,不需要重启。因为系统通过inode号码,识别运行中的文件,不通过文件名。更新的时候,新版文件以同样的文件名,生成一个新的inode,不会影响到运行中的文件。等到下一次运行这个软件的时候,文件名就自动指向新版文件,旧版文件的inode则被回收。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值