什么是 inode

inode 的定义:Unix 文件系统中的一种数据结构,用来存储文件的元信息数据

 

文件在硬盘中的存储是以"块"(block)为单位的,常见的块大小是 4k

一个稍微大一点的文件则会存储在多个块中,那么如何快速访问到这些数据呢?答案就是 inode

 

在文件系统中,每个文件对象都对应着一个 inode,其中存储着常用的一些信息(所有者、创建时间、修改时间、文件权限、对应文件对象在系统中存储块的位置等等)

操作系统访问一个文件时分为三个步骤:

  1. 通过文件名找到对应的 inode 编号
  2. 通过 inode 编号访问对应文件对象的元信息
  3. 根据元信息找到文件对应的 block,读取数据

从上面的描述可以看出,inode 实际上就是文件系统中的一种索引,便于管理文件以及快速访问数据

关于 inode 的一些细节

inode 的内容

POSIX 标准定义了 inode 所包含的信息:

  • 以字节为单位表示的文件大小
  • 设备ID,标识容纳该文件的设备
  • 文件所有者的 User ID
  • 文件的 Group ID
  • 文件的模式(mode),确定了文件的类型,以及它的所有者、它的 group、其它用户访问此文件的权限
  • 额外的系统与用户标志(flag),用来保护该文件
  • 3 个时间戳,记录了 inode 自身被修改(ctime, inode change time)、文件内容被修改(mtime, modification time)、最后一次访问(atime, access time)的时间
  • 1 个链接数,表示有多少个硬链接指向此inode
  • 指向文件系统存储位置的指针

使用 stat 命令可以查询一个文件的 inode 编号及对应的文件元信息:

inode 的存储

inode 存储文件对象的元信息,也会占用一部分磁盘空间

当文件系统创建(格式化)时,会把存储区域分为两大连续的区域,其中一个用来保存 inode,称为 inode table,每个 inode 默认 128 or 256 字节

另一块区域则用来保存文件的数据块

从这里可以看出,一个文件系统中 inode 的数量在初始化时确定了,inode 的数量和磁盘大小成正比

查看每个硬盘分区的 inode 总数和已经使用的数量,可以使用 df 命令:

由于每个文件都会对应一个 inode,当磁盘中存在大量小文件时,就可能出现磁盘空间有空闲但是 inode 用完的情况

例如一个电子邮件服务器可能会存在大量 eml 文件使磁盘 inode 耗尽,无法入信新邮件

所以一般大型的邮件系统都会设计自己的文件系统来存储邮件数据,如使用信桶(mbox)文件结构来存储单个用户的所有邮件数据

目录文件、硬链接和软链接

Linux 中一切皆文件,目录也是文件的一种,每个目录项包含两部分:目录中所有文件的文件名、所有文件名对应的 inode 编号

使用 ls -i 命令查看目录的内容:

如果想要查看该目录下文件的详细信息,那么就需要根据每个文件的 inode 编号,找到对应的 inode 访问元信息:

 

上述 inode 中包含的信息中,可以发现并不存在文件名这一信息,实际上在 Unix 环境下,一个文件对象可以对应多个文件名,即硬链接(hard link)

 

使用 ln 命令可以创建硬链接:

ln 源文件 目标文件



上图中 f1.txt f2.txt 都指向同一个 inode,修改其中一个文件内容会影响到另一个

从 inode 内容中可以发现有一个链接数,当我们创建了一个硬链接时,所对应的文件的 inode 中链接数就会 +1,表示其对应的文件名(引用计数)+1

同理,当删除一个文件后,该链接数将 -1,链接数为 0 时文件数据就被完全清除了

 

与硬链接对应的还有软链接,使用 ln -s 命令可以创建软链接:

ln -s 源文文件或目录 目标文件或目录



软链接和硬链接的区别在于,软链接指向其链接的文件名,而不是 inode,一个软链接有自己的 inode

删除其指向的文件后,该软链接则不可访问(No such file or directory)

 

这里的设计类似于 C++ 中指针和引用,硬链接可以类比为引用,而软链接则是指针,其中保存着文件名(访问文件数据的地址)

而 inode 链接数则和智能指针的引用计数设计思路相似,不得不说计算机系统中很多设计都有共通性

inode 的其他作用

由于硬链接的存在,文件名和 inode 是多对一的关系,操作系统打开一个文件后就抛弃了文件名,只保留 inode 编号来访问文件内容

库函数 getcwd() 的实现,就是从当前工作目录的 inode 逐级查找上级目录的 inode,最后拼出完整的绝对路径

 

inode 的设计,使得在操作系统中安装/更换新的库文件十分方便

当一些进程还在使用库时,其他进程可以替换该库文件 inode 编号指向新创建的 inode,后面对该库的访问都被引导至新库文件的内容,减少了替换库时重启系统的必要

由于旧的 inode 中链接数已经为 0,在使用旧库的进程结束后,旧的 inode 和旧库文件将被文件系统自动回收


参考文献

理解inode -- 阮一峰的网络日志

inode -- wikipedia

Linux 文件系统 -- inode 笔记的更多相关文章

  1. # linux文件系统(inode block superblock)

    先说一下格式化:每种操作系统所设置的文件属性/权限并不相同,为了存放这些文件所需的数据,因此就需要将分区格式化,以成为操作系统能够利用的文件系统格式.linux的文件格式为Ext2/Ext3,现在好像 ...

  2. Linux文件系统inode、block解释权限(三)

    利用文件系统的inode和block来分析文件(目录)的权限问题. 为什么读取一个文件还要看该文件路径所有目录的权限? 为什么目录的w权限具有删除文件的能力,而文件w权限不行. inode:记录文件的 ...

  3. Linux文件系统学习笔记-1

       在Linux中, 一切皆文件,不论是目录,设备,套接字等都可以看成文件,而且每一个文件对应一个inode号,这是一一对应的关系. [root@oracle ~]# ls -il 总用量 2624 ...

  4. linux 文件系统(inode和block)

    linux文件系统(inode block superblock)   先说一下格式化:每种操作系统所设置的文件属性/权限并不相同,为了存放这些文件所需的数据,因此就需要将分区格式化,以成为操作系统能 ...

  5. [apue] linux 文件系统那些事儿

    前言 说到 linux 的文件系统,好多人第一印象是 ext2/ext3/ext4 等具体的文件系统,本文不涉及这些,因为研究具体的文件系统难免会陷入细节,甚至拉大段的源码做分析,反而不能从宏观的角度 ...

  6. Linux文件系统与inode、Block笔记

    Linux文件系统与inode.Block笔记 在Linux下一切都是文件,无论是设备还是接口,亦或是网卡等均被抽象成了文件,并且有相关的内核代码进行调度.然而,在一切都是文件的前提下,最需要进行探讨 ...

  7. 理解Linux文件系统之inode

    很少转发别人的文章,但是这篇写的太好了. 理解inode   作者: 阮一峰 inode是一个重要概念,是理解Unix/Linux文件系统和硬盘储存的基础. 我觉得,理解inode,不仅有助于提高系统 ...

  8. [转]理解Linux文件系统之inode

    很少转发别人的文章,但是这篇写的太好了. 理解inode   作者: 阮一峰 inode是一个重要概念,是理解Unix/Linux文件系统和硬盘储存的基础. 我觉得,理解inode,不仅有助于提高系统 ...

  9. 学习笔记:CentOS7学习之十四:linux文件系统

    目录 1. 机械硬盘结构 1.1 机械硬盘结构 1.2 簇和block 2.文件系统结构 2.1 文件名 2.2 inode的内容 2.3 inode的大小 2.4 目录文件 2.5 block块大小 ...

随机推荐

  1. docker oracle install

    https://hub.docker.com/r/9fevrier/oracle-11g Informations Oracle directory : /opt/oracle Data direct ...

  2. 洛谷P3366 【模板】最小生成树(kuskal)

    #include<bits/stdc++.h> using namespace std; ; ; struct node{ int cnt,fa; }f[maxn]; inline voi ...

  3. [Offer收割]编程练习赛108 - 树上的最短边 树链剖分

    直接点权下放到边权,每次查询从dfs序的st[u]+1,ed[v]之间查询, #include<iostream> #include<stdio.h> #include< ...

  4. uva 10253 Series-Parallel Networks (整数划分+多重集)

    UVa Online Judge 题意是计算给定数量的边通过串联并联两种方式,能组成多少种不同的网络.将它转化为一个树形结构,也就是求有多少不同构的树. 代码如下: #include <cstd ...

  5. 20190527-JavaScriptの打怪升级旅行 { 语句 [ 声明 ,变量 ] }

    写在前面的乱七八糟:时间总是轻易地溜走,不留一丝念想,近一个月,倒是过得有点丧,从今天开始起,已经开始接触后台了,而JavaScript也只是大致有了个分类框架,那些细枝末节还有的补,任重道远,天将降 ...

  6. ELMo解读(论文 + PyTorch源码)

    ELMo的概念也是很早就出了,应该是18年初的事情了.但我仍然是后知后觉,居然还是等BERT出来很久之后,才知道有这么个东西.这两天才仔细看了下论文和源码,在这里做一些记录,如果有不详实的地方,欢迎指 ...

  7. Java1.8 获取文件总行数

    Files.lines(Paths.get("aaa.txt")).count();

  8. Python--day25--面向对象之封装

    狭义上的封装的例子:(例1)Python就只有两种类型:公有和私有,没有Java中说的那种保护类型 例2: 例3:正常的方法调用私有方法 封装总结:

  9. Element节点输出到System.out

    protected void writeElementToFile(Element valrespEle) { try { TransformerFactory transformerFactory ...

  10. 深入理解 Embedding层的本质

    继上文https://blog.csdn.net/weixin_42078618/article/details/82999906探讨了embedding层的降维效果,时隔一个月,分享一下嵌入层在NP ...