首页 > 其他分享 >文件系统

文件系统

时间:2023-08-29 20:23:18浏览次数:39  
标签:文件 文件名 inode 文件系统 数据 空闲

小林coding 《图解系统:文件系统》笔记

 

Linux 最经典的一句话是:「一切皆文件」,不仅普通的文件和目录,就连块设备、管道、socket 等,也都是统一交给文件系统管理的。

Linux 支持的文件系统也不少,根据存储位置的不同,可以把文件系统分为三类:

  • 磁盘的文件系统,它是直接把数据存储在磁盘中,比如 Ext 2/3/4、XFS 等都是这类文件系统。
  • 内存的文件系统,这类文件系统的数据不是存储在硬盘的,而是占用内存空间,我们经常用到的 /proc 和 /sys 文件系统都属于这一类,读写这类文件,实际上是读写内核中相关的数据。
  • 网络的文件系统,用来访问其他计算机主机数据的文件系统,比如 NFS、SMB 等等。

文件系统的种类众多,而操作系统希望对用户提供一个统一的接口,于是在用户层与文件系统层引入了中间层,这个中间层就称为虚拟文件系统Virtual File System,VFS)。

VFS 定义了一组所有文件系统都支持的数据结构和标准接口,这样程序员不需要了解文件系统的工作原理,只需要了解 VFS 提供的统一接口即可。

 

文件系统

文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息:inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。

总之,除了文件名以外的所有文件信息,都存在inode之中(inode 在磁盘中)。

可以用stat命令,查看某个文件的inode信息:

硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。

每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定。

由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。

每个inode都有一个号码,操作系统用inode号码来识别不同的文件。

Unix/Linux系统内部不使用文件名,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。

目录也是一种文件

Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。

目录文件的结构非常简单,就是一系列目录项(dirent)的列表。

每个目录项,由两部分组成:所包含文件的文件名,以及该文件名对应的inode号码。通过这个 inode,就可以找到真正的文件。

目录查询是通过在磁盘上反复搜索完成,需要不断地进行 I/O 操作,开销较大。所以,为了减少 I/O 操作,把当前使用的文件目录缓存在内存。

表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:文件名 ——>对应的inode号码——>inode信息——>文件数据所在的block

 

 

读取文件过程

  • 首先用 open 系统调用打开文件,open 的参数中包含文件的路径名和文件名。
  • 使用 write 写数据,其中 write 使用 open 所返回的文件描述符,并不使用文件名作为参数。
  • 使用完文件后,要用 close 系统调用关闭文件,避免资源的泄露。

我们打开了一个文件后,操作系统会跟踪进程打开的所有文件,所谓的跟踪呢,就是操作系统为每个进程维护一个打开文件表,文件表里的每一项代表「文件描述符」,所以说文件描述符打开文件的标识。

操作系统在打开文件表中维护着打开文件的状态和信息:

  • 文件指针:系统跟踪上次读写位置作为当前文件位置指针
  • 文件打开计数器:多个进程可能打开同一个文件,该计数器跟踪打开和关闭同一文件的进程数量,当该计数为 0 时,系统关闭文件,删除该条目;
  • 文件磁盘位置:保存在内存中,以免每个操作都从磁盘中读取;
  • 访问权限:每个进程打开文件都需要有一个访问模式(创建、只读、读写、添加等)

用户习惯以字节的方式读写文件,而操作系统则是以数据块来读写文件,那屏蔽掉这种差异的工作就是文件系统了。

我们来分别看一下,读文件和写文件的过程:

  • 当用户进程从文件读取 1 个字节大小的数据时,文件系统则需要获取字节所在的数据块,再返回数据块对应的用户进程所需的数据部分。
  • 当用户进程把 1 个字节大小的数据写进文件时,文件系统则找到需要写入数据的数据块的位置,然后修改数据块中对应的部分,最后再把数据块写回磁盘。

所以说,文件系统的基本操作单位是数据块。

 

文件的存储

磁盘读写的最小单位是扇区,扇区的大小只有 512B 大小,很明显,如果每次读写都以这么小为单位,那这读写的效率会非常低。

所以,文件系统把多个扇区组成了一个逻辑块,每次读写的最小单位就是逻辑块(数据块)Linux 中的逻辑块大小为 4KB,也就是一次性读写 8 个扇区,这将大大提高了磁盘的读写的效率。

数据块在磁盘上的存放方式有以下两种:

  • 连续空间存放方式
  • 非连续空间存放方式

其中,非连续空间存放方式又可以分为「链表方式」和「索引方式」。

 那早期 Unix 文件系统是组合了前面的文件存放方式的优点,如下图:

最前面那块就是 inode

它是根据文件的大小,存放的方式会有所变化:

  • 如果存放文件所需的数据块小于 10 块,则采用直接查找的方式;
  • 如果存放文件所需的数据块超过 10 块,则采用一级间接索引方式;
  • 如果前面两种方式都不够存放大文件,则采用二级间接索引方式;
  • 如果二级间接索引也不够存放大文件,这采用三级间接索引方式;

所以,这种方式能很灵活地支持小文件和大文件的存放:

  • 对于小文件使用直接查找的方式可减少索引数据块的开销;
  • 对于大文件则以多级索引的方式来支持,所以大文件在访问数据块时需要大量查询;

 

空闲空间管理

  • 空闲表法:为所有空闲空间建立一张,表内容包括空闲区的第一个块号该空闲区的块个数,注意,这个空闲表是连续分配的。如果存储空间中有着大量的小的空闲区,则空闲表变得很大,这样查询效率会很低。
  • 空闲链表法:每一个空闲块里有一个指针指向下一个空闲块。只要在主存中保存一个指针,令它指向第一个空闲块。其特点是简单,但不能随机访问。

空闲表法和空闲链表法都不适合用于大型文件系统,因为这会使空闲表或空闲链表太大。

  • 位图法:利用二进制的一位来表示磁盘中一个盘块的使用情况,磁盘上所有的盘块都有一个二进制位与之对应。0 表示对应的盘块空闲,1 表示对应的盘块已分配。

 

块组

文件读写的最小单位是块,按照块存放的数据类型划分,有不同类型的块:

  • inode(index node)索引块:每个文件都有一个inode来唯一标志文件
  • 数据块:包含文件的有用数据。
  • 数据位图块 和 inode位图块:用于表示对应的数据块或 inode 是空闲的,还是被使用中。

  • 超级块:包含的是文件系统的重要信息,比如 inode 总个数、块总个数、每个块组的 inode 个数、每个块组的块个数等等。
  • 块组描述符:包含文件系统中各个块组的状态,比如块组中空闲块和 inode 的数目等,每个块组都包含了文件系统中「所有块组的组描述符信息」。

 

基于inode的文件共享(硬链接)

一般情况下,文件名和inode号码是"一一对应"关系,每个inode号码对应一个文件名。但是,Unix/Linux系统允许,多个文件名指向同一个inode号码。这意味着,可以用不同的文件名访问同样的内容;对文件内容进行修改,会影响到所有文件名;但是,删除一个文件名,不影响另一个文件名的访问。这种情况就被称为"硬链接"(hard link)。

ln 命令可以创建硬链接:ln 源文件 目标文件

 

基于文件名的文件共享(软链接)

软链接相当于重新创建一个软链接文件,这个文件有独立的 inode,但是这个文件的内容是另外一个文件的文件名,所以访问软链接的时候,实际上相当于访问到了另外一个文件,所以软链接是可以跨文件系统的,甚至目标文件被删除了,链接文件还是在的,只不过指向的文件找不到了而已,打开文件就会报错:"No such file or directory"。

这是软链接与硬链接最大的不同:文件A指向文件B的文件名,而不是文件B的inode号码,文件B的inode"链接数"不会因此发生变化。

ln -s 命令可以创建软链接:ln -s 源文文件或目录 目标文件或目录。

 

 

 

 

inode 的特殊作用

由于inode号码与文件名分离,这种机制导致了一些Unix/Linux系统特有的现象。

  1. 有时,文件名包含特殊字符,无法正常删除。这时,直接删除inode节点,就能起到删除文件的作用。

  2. 移动文件或重命名文件,只是改变文件名,不影响inode号码。

  3. 打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名。因此,通常来说,系统无法从inode号码得知文件名。

      第3点使得软件更新变得简单,可以在不关闭软件的情况下进行更新,不需要重启。因为系统通过inode号码,识别运行中的文件,不通过文件名。更新的时候,新版文件以同样的文件名,生成一个新的inode,不会影响到运行中的文件。等到下一次运行这个软件的时候,文件名就自动指向新版文件,旧版文件的inode则被回收。

 

标签:文件,文件名,inode,文件系统,数据,空闲
From: https://www.cnblogs.com/suBlog/p/17665745.html

相关文章

  • 服务器数据恢复-IBM服务器reiserfs文件系统数据恢复案例
    服务器数据恢复环境:一台IBMX系列服务器,4块SAS硬盘组建一组RAID5阵列,采用的reiserfs文件系统。服务器操作系统分区结构:boot分区+LVM卷+swap分区(按照前后顺序)。LVM卷中直接划分了一个reiserfs文件系统,作为根分区。服务器故障:服务器在运行过程中由于未知原因瘫痪,管理员将服务器重......
  • buildroot 构建根文件系统(2)开机自启动脚本
    一、开发背景构建最小系统后成功运行后,有些应用或者脚本需要开机自启动,不要手动操作二、开发需求开机启动用户路径下的test.sh脚本/root/test.sh三、开发环境LinuxUbuntu 4.15.0-65-generic+ buildroot-2023.02.3+i.mx6d(cortex-A9)四、实现步骤1......
  • buildroot 构建根文件系统(2)使能 SSH
    一、开发背景承接上一章节,构建最小系统后成功运行后,发现没有SSH功能SSH:SecureShellProtocol,开发阶段常用SSH远程传输文件,只要匹配IP地址即可二、开发需求配置系统使能SSH功能三、开发环境LinuxUbuntu 4.15.0-65-generic+ buildroot-2023.0......
  • Linux查看磁盘空间,文件系统、挂载
    Linux磁盘空间,文件系统、挂载概述在使用以下命令查看磁盘使用情况时df-hdu-sh目标路径作为初级开发者,Linux入门级选手,可能不禁要问Linux系统的文件系统跟windows的区别?什么是挂载?Linux系统的文件系统分区跟windows的区别Windows的目录结构属于分区而Linux分区......
  • [转载]修复容器中的top指令以及/proc文件系统中的信息
    如何修复容器中的top指令以及/proc文件系统中的信息呢?通过lxcfs解决Docker和Kubernetes环境中解决遗留应用无法识别容器资源限制的问题。wgethttps://copr-be.cloud.fedoraproject.org/results/ganto/lxd/epel-7-x86_64/00486278-lxcfs/lxcfs-2.0.5-3.el7.centos.x86_64.rpmyu......
  • Linux系统:第四章:Linux文件系统
    Linux文件系统 概述Linux系统中只有一个文件系统,以“/”作为根目录,从根目录出发可以找到任何一个文件和目录。这样就有了一个访问目录、文件的统一规范。在根目录下的诸多目录都有特定的作用,其中有些目录对我们日常操作来说非常的重要。[bin]是binary的缩写,这个目录存放着......
  • 常见磁盘文件系统格式
    NTFS(win)最大分区2TB,支持大文件读写目前多用于电脑、移动硬盘等各种大中型空间容量的磁盘。FAT16:最大分区2GB,我们以前用的DOS、Windows95都使用FAT16文件系统FAT32(win)最大分区2TB,兼容性好些,适合移动存储却多用于U盘、内存卡等小型磁盘ext3和ext4是linux文件系统格式Ext3目前......
  • uboot 通过网络启动内核和根文件系统
    一、开发背景由于开发阶段需要频繁修改内核镜像文件和根文件系统,如果每次修改都通过烧写emmc或者烧录sd卡制卡过于繁琐,所以需要通过网络启动和加载二、开发需求内核镜像文件(zImage)和根文件系统(rootfs)创建好后,存放于Ubuntu中,开发板启动过程中自动提取对应的文件。......
  • buildroot 构建根文件系统
    一、开发背景原开发板的文件系统拥有很大的冗余文件,需要裁剪文件系统或者根据需要定制文件系统二、开发需求1、构造最小系统,支持基本指令,例如cd、ls、tar等基础指令三、开发环境LinuxUbuntu 4.15.0-65-generic+ buildroot-2023.02.3+i.mx6d(cortex-A9)......
  • Ubuntu22.04(禁用)彻底删除Snap以及出现“rm: 无法删除"XXX":只读文件系统”的解决方案
    Ubuntu22.04(禁用)彻底删除Snap以及出现”rm:无法删除"XXX":只读文件系统“的解决方案导语Snaps是Ubuntu的母公司Canonical于2016年4月发布Ubuntu16.04LTS(LongTermSupport,长期支持版)时引入的一种容器化的软件包格式。自Ubuntu16.04LTS起,Ubuntu操作系......