Linux文件系统与硬盘存储(分区格式化挂载inode软链接与硬链接)
Posted Jacky_Feng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux文件系统与硬盘存储(分区格式化挂载inode软链接与硬链接)相关的知识,希望对你有一定的参考价值。
一、Linux系统的文件存储结构
在Linux系统中,目录、字符设备、套接字、硬盘、光驱、打印机等都被抽象成文件形式(“Linux系统一切皆文件”)。既然平时我们打交道的都是文件,那么又应该如何找到它们呢?
在Windows操作系统中,想要找到一个文件,要依次进入该文件所在的磁盘分区(也叫盘符),然后再进入该分区下的具体目录,最终找到这个文件。
但是在Linux系统中并不存在C、D、E、F等盘符,Linux系统中的一切文件都是从“根”目录(/)开始的,并按照文件系统层次标准(FHS)采用倒树状结构来存放文件,以及定义了常见目录的用途。
FHS是根据以往无数Linux系统用户和开发者的经验而总结出来的,是用户在Linux系统中存储文件时需要遵守的规则,用于指导用户应该把文件保存到什么位置,以及告诉用户应该在何处找到所需的文件。FHS对于用户来讲只能算是一种道德上的约束,并非必须遵循。
Linux系统中的文件和目录名称是严格区分大小写的。例如,root、rOOt、Root、rooT均代表不同的目录,并且文件名称中不得包含斜杠(/)。
(1) Linux系统中的文件存储结构
(2)Linux系统中常见的目录名称以及相应内容
目录名称 | 应放置文件的内容 |
/boot | 开机所需文件—内核、开机菜单以及所需配置文件等 |
/dev | 以文件形式存放任何设备与接口 |
/etc | 配置文件 |
/home | 用户主目录 |
/bin | 存放单用户模式下还可以操作的命令 |
/lib | 开机时用到的函数库,以及/bin与/sbin下面的命令要调用的函数 |
/sbin | 开机过程中需要的命令 |
/media | 用于挂载设备文件的目录 |
/opt | 放置第三方的软件 |
/root | 系统管理员的家目录 |
/srv | 一些网络服务的数据文件目录 |
/tmp | 任何人均可使用的“共享”临时目录 |
/proc | 虚拟文件系统,例如系统内核、进程、外部设备及网络状态等 |
/usr/local | 用户自行安装的软件 |
/usr/sbin | Linux系统开机时不会使用到的软件/命令/脚本 |
/usr/share | 帮助与说明文件,也可放置共享文件 |
/var | 主要存放经常变化的文件,如日志 |
/lost+found | 当文件系统发生错误时,将一些丢失的文件片段存放在这里 |
(3) 路径
Linux系统的路径指如何定位到某个文件,分为绝对路径和相对路径。
- 绝对路径:从根目录(/)开始写起的文件或目录名称
- 相对路径:相对于当前路径的写法
(4)常见的物理(硬件)设备及其文件名称
在Linux系统中一切都是文件,硬件设备也不例外。既然是文件,就必须有文件名称。系统内核中的udev设备管理器会自动把硬件名称规范起来,目的是让用户通过设备文件的名字可以猜出设备大致的属性以及分区信息等;这对于陌生的设备来说特别方便。另外,udev设备管理器的服务会一直以守护进程的形式运行并侦听内核发出的信号来管理/dev目录下的设备文件。
常用的硬件设备及其文件名称:
硬件设备 | 文件名称 |
IDE设备 | /dev/hd[a-d] |
SCSI/SATA/U盘 | /dev/sd[a-z] |
virtio设备 | /dev/vd[a-z] |
软驱 | /dev/fd[0-1] |
打印机 | /dev/lp[0-15] |
光驱 | /dev/cdrom |
鼠标 | /dev/mouse |
磁带机 | /dev/st0或/dev/ht0 |
一般的硬盘设备都是以“/dev/sd”开头。而一台主机上可以有多块硬盘,因此系统采用a~z来代表26块不同的硬盘(默认从a开始分配)。
磁盘的分区:
- 主分区或扩展分区的编号从1开始,到4结束;
- 逻辑分区从编号5开始。
【注意】对于分区名称sda3只能表示是编号为3的分区,而不能判断sda设备已经存在了3个分区。
示例:/dev/sda5
表示“这是系统中第一块被识别到的硬件设备中分区编号为5的逻辑分区的设备文件”
二、硬盘设备及分区
硬盘的基础概念
- 一个硬盘有多张盘片叠成,不同盘片有编号
- 每张盘片上的存储颗粒成环形一圈圈地排布,每一圈称为磁道,有编号
- 每条磁道上都有一圈存储颗粒,每512*8(512字节,0.5KB)个存储颗粒作为一个扇区,扇区是硬盘上存储的最小物理单位
- N个扇区可以组成簇,N取决于不同的文件系统或是文件系统的配置,簇是此文件系统中的最小存储单位
- 所有盘面上的同一磁道构成一个圆柱,称为柱面,柱面是系统分区的最小单位
硬盘设备是由大量的扇区组成的,每个扇区的容量为512字节。其中第一个扇区最重要,它里面保存着主引导记录(Master boot record,MBR)与分区表(partition table)信息。硬盘主引导记录放有最基本的引导加载程序(boot loader),是系统开机启动的关键环节。而分区表则跟分区有关,它记录了硬盘分区的相关信息。
分区存储的信息:分区号(partition id)、分区的起始柱面和分区的柱面数量。Linux操作系统在初始化时就可以根据分区表中三种信息来识别硬盘设备。
主引导记录需要占用446字节,分区表占用64字节,结束符占用2字节;其中分区表中每记录一个分区信息就需要16字节,这样一来最多只有4个分区信息可以写到第一个扇区中,这4个分区就是4个主分区。
第一个扇区中的数据信息:
【问题】每块硬盘最多只能创建4个分区吗?
这显然是不合理也不够用的。为解决分区个数不够的问题,可以将第一个扇区的分区表中16字节(原本要写入主分区信息)的空间(称之为“扩展分区”)拿出来指向另一个分区。所以,扩展分区其实不是一个真正的分区,更像是一个占用16字节分区表空间的指针(一个指向另一个分区的指针)。这样,用户一般会选择使用3个主分区加1个扩展分区的方法,然后再扩展分区中创建出数个逻辑分区,从而满足多分区(>4个分区)的要求。
扩展分区自身不能存储数据,用户需要在其指向的对应分区(称为“逻辑分区”)上进行操作。
为什么要进行分区?
(1)易于管理和使用:
比如说我们把磁盘分了sda1、sda2、sda3、sda4盘,我们假设sda1盘为系统盘,其他的比如说游戏、办公、软件盘,这样我们要重新分哪个区就直接在对应的盘分就可以了,不需要整块磁盘进行分区。根据用途我们也能较快的去使用相应的磁盘。
(2)有利于数据的安全:
通过分区可以降低数据损失的风险。出现硬盘坏道、错误操作、重装系统都有可能造成数据损失,如果分区了,那么我们就可以将损失最小化。
(3)节约寻找文件的时间:
分区以后,电脑搜索文件时只需要在相对应的分区搜索就可以了,没必要进行全盘搜索。大大节省了寻找文件的时间。
Linux 创建分区命令
(1)查看分区情况:lsblk
(2)使用fdisk工具创建分区
fdisk工具命令集合:
①启动fdisk工具(使用管理员权限)
②创建一个分区n(new的缩写)
③查看分区p(打开分区列表)
④删除分区d (delete缩写)
⑤保存分区并写入磁盘
三、文件系统
用户在硬件存储设备中执行的文件建立、写入、读取、修改、转存与控制等操作都是依靠文件系统来完成的。文件系统的作用是合理规划硬盘,以保证用户正常的使用需求。
Linux系统支持数十种文件系统,而最常见的文件系统如下所示。
Ext2:最早可追溯到1993年,是Linux系统的第一个商业级文件系统,它基本沿袭了UNIX文件系统的设计标准。但由于不包含日志读写功能,数据丢失的可能性很大,因此大家能不用就不用,或者顶多建议用于SD存储卡或U盘。
Ext3:是一款日志文件系统,它会把整个硬盘的每个写入动作的细节都预先记录下来,然后再进行实际操作,以便在发生异常宕机后能回溯追踪到被中断的部分。Ext3能够在系统异常宕机时避免文件系统资料丢失,并能自动修复数据的不一致与错误。然而,当硬盘容量较大时,所需的修复时间也会很长,而且也不能100%地保证资料不会丢失。
Ext4:Ext3的改进版本,作为RHEL 6系统中默认的文件管理系统,它支持的存储容量高达1EB(1EB=1,073,741,824GB),且能够有无限多的子目录。另外,Ext4文件系统能够批量分配block(块),从而极大地提高了读写效率。现在很多主流服务器也会使用Ext4文件系统。
XFS:是一种高性能的日志文件系统,而且是RHEL 7/8中默认的文件管理系统。它的优势在发生意外宕机后尤其明显,即可以快速地恢复可能被破坏的文件,而且强大的日志功能只需花费极低的计算和存储性能。它支持的最大存储容量为18EB(18EB等于18,874,368TB。假设每块硬盘的容量是100TB,那么大概需要19万块硬盘才能把18EB的数据都装下。),这几乎满足了所有需求。
在拿到一块新的硬盘存储设备后,先需要分区,然后再格式化文件系统,最后才能挂载并正常使用。硬盘的分区操作取决于您的需求和硬盘大小;也可以选择不进行分区,但是必须对硬盘进行格式化处理。
类比:就像拿到了一张未裁切的完整纸张那样,首先要进行裁切以方便使用(分区),接下来在裁切后的纸张上画格以便能书写工整(格式化),最后是正式的使用(挂载)。
四、硬盘格式化
Linux操作系统支持很多不同的文件系统,比如ext2、ext3、XFS等等,而Linux把对不同文件系统的访问交给了VFS(虚拟文件系统),VFS能访问和管理各种不同的文件系统。所以分区完需要把它格式化成具体的文件系统以便VFS访问。
标准的Linux文件系统Ext2是使用「基于inode的文件系统」
文件的存储:
(1)文件系统通常会将文件的属性和实际内容这两部分数据分别存放在不同的区块
(2)在基于inode的文件系统中,权限与属性放置到 inode 中,实际数据放到 data block 区块中,而且inode和data block都有编号
存储划分:
(1)文件系统最前面有一个启动扇区(boot sector)
这个启动扇区可以安装开机管理程序, 这个设计让我们能将不同的引导装载程序安装到个别的文件系统前端,而不用覆盖整个硬盘唯一的MBR, 也就是这样才能实现多重引导的功能。
(2)把每个区进一步分为多个块组 (block group),每个块组有独立的inode/block体系
每个块组实际还会分为分为6个部分,除了inode table 和 data block外还有4个附属模块,起到优化和完善系统性能的作用。
Linux 格式化命令
格式化命令mkfs
参数指定:
-t : 指定文件系统的类型,Linux 的预设值为ext2,可以指定为ext3,4等
( Windows下的文件系统有Fat32、NTFS,CentOS使用的文件系统为ext,之前centOS5版本使用ext3作为默认的文件系统,而CentOS6使用ext4作为默认的文件系统)
mkfs本身并不执行建立文件系统的工作,而是去调用相关的程序来执行。例如,若在"-t" 参数中指定ext2,则 mkfs会调用mke2fs 来格式化创建文件系统。
mkfs.ext3 mkfs.reiserfs mkfs.ext2 mkdosfs mkfs.msdos mkfs.vfat ,通过文件名,我们知道这些工具是支持什么文件系统。
文件系统存储结构
ExtX文件系统存储结构如下图所示:
Super block(超级块):存放文件系统本身的结构信息。记录的主要信息:
- block和inode的总量、使用量、未使用量
- block和inode的大小
- 文件系统的最近一次挂载时间、最近一次写入数据的时间等
- 一个validbit 数值,若此文件系统已被挂载,则valid bit为0,否则为1
GDT(Group Description Table ,块组描述符):描述每个块组属性信息。包括块组(block group)的开始与结束号,以及说明每个段区(superblock、bitmap、inode map、data block)分别介于哪个block号之间。
inode Bitmap(inode 位图):每个bit表示一个inode是否空闲可用。
Block Bitmap(块位图):记录着Data block 数据块的占用情况。
inode Table(节点表):记录文件的属性以及文件实际数据的位置。
(每个文件仅占用一个inode,每个inode大小固定为128字节,记录一个block消耗4字节。当文件的inode被写满后,Linux系统会自动分配出一个block,专门用于像inode那样记录data block块的信息)
- 该文件的访问权限(read、write、execute);
- 该文件的所有者与所属组(owner、group);
- 该文件的大小(size);
- 该文件的创建或内容修改时间(Ctime);
- 该文件的最后一次访问时间(Atime);
- 该文件的修改时间(Mtime);
- 文件的特殊权限(SUID、SGID、SBIT);
- 该文件的真实数据地址(point)。
Data Block(数据块):存放具体文件内容。
文件系统中所支持的 block 大小通常有1kB、2KB及4KB三种。在格式化时,block的大小就固定了,且每个block都有编号,以便inode记录。由于block大小的差异,会导致该文件系统能够支持的最大磁盘容量与最大单一文件容量并不相同。
对于存储文件内容的block块,有下面两种常见的情况(以4KB大小的block为例进行说明)
- 情况1:文件很小(1KB),但依然会占用一个block(剩余容量不会被使用),因此会潜在地浪费3KB。
- 情况2:文件很大(5KB),那么会占用两个block(5KB−4KB后剩下的1KB也要占用一个block)。
Block 大小 | 1KB | 2KB | 4KB |
最大单一文件限制 | 16GB | 256GB | 2TB |
最大文件系统总容量 | 2TB | 8TB | 16TB |
最大单一文件容量的计算方法
一个文件对应一个inode。ext2文件系统为了让inode记录尽可能多的data block,定义了四个记录block号码的区域,分别为12个直接记录区,1个间接记录区,1个双间接记录区,1个三间接记录区,所谓间接记录区就是用data block记录data block号码.
以每个 block 的大小1KB为例:
(1) 12个直接指向:12 × 1K = 12 K (一个直接记录区记录一个data block号码,一个data block 1K)
(2) 1个间接:256 × 1K = 256 K (一次间接指针指向一个data block,由该data block间接记录文件data block号码,由于data block为1K,记录一个data block要4byte,所以一个data block可以保持1024 / 4 = 256 个data block号码)
(3) 1个双间接:256 × 256 × 1K = 65526 K
(4)1个三间接:256 × 256 × 256 × 1K = 16,777,216K
最大单一文件容量等于四个记录区容量的总和,12 + 256 + 65526 + 6,777,216 = 116,843,010 K,约等于16G。
【注意】该方法仅限于<2k的block,受到文件系统本身的限制,ext2文件系统限制单个文件最大容量为2T。
虚拟文件系统(Virtual File System,VFS)
为了使用户在读取或写入文件时不用关心底层的硬盘结构,Linux内核中的软件层为用户程序提供了一个虚拟文件系统(Virtual File System,VFS)接口,这样用户实际上在操作文件时就是统一对这个虚拟文件系统进行操作了,如下VFS的架构示意图所示。从中可见,实际文件系统在VFS下隐藏了自己的特性和细节,这样用户在日常使用时会觉得“文件系统都是一样的”,也就可以随意使用各种命令在任何文件系统中进行各种操作了。
使用Linux命令查看inode信息
(1) 查看文件的inode信息:stat
(2) 查看文件类型:file
(3) 查看inode号码:ls -i
(可以看到stat命令中也有Inode,22360就是inode号)
(4) 查看硬盘分区的inode数量和使用情况:df -i
五、挂载
在一个区被格式化为一个文件系统之后,它就可以被Linux操作系统使用了,只是这个时候Linux操作系统还找不到它,所以我们还需要把这个文件系统注册进Linux操作系统的文件体系里,这个操作就叫挂载 (mount)。
挂载是利用一个已存在的目录文件当成进入点(类似选一个现成的目录作为代理),将文件系统放置(关联)在该目录下,也就是说,进入该目录就可以读取该文件系统的内容,类似整个文件系统只是目录树的一个文件夹(目录)。
这个进入点的目录我们称为挂载点。
由于整个 Linux 系统最重要的是根目录,因此根目录一定需要挂载到某个分区。 而其他的目录则可依用户自己的需求来给予挂载到不同的分去。
【小结】
硬盘经过分区和格式化,每个区都成为了一个文件系统,挂载这个文件系统后就可以让Linux操作系统通过VFS访问硬盘时跟访问一个普通文件夹一样。
Linux挂载和卸载命令
挂载mount
卸载umount
强制卸载加参数-l
六、文件寻址(文件读取)
一个文件由一个目录项、inode、数据区域块组成。
目录结构:
在 Linux 下的 ext2 文件系统创建一个目录时, ext2 会分配一个 inode 与至少一块 block 给该目录。
inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码
block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据.
如下图所示:
上面的图描述的是查看文件的流程,从图中可以看出 tmp/ 目录文件对应的 Block 块中存储的是该目录下文件名以及文件名对应的 inode 号码,而 a.txt、c.txt 文件对应的 Block 块中存储的是 a.txt c.txt 文件的内容
由于目录树是由根目录(/)开始读起,因此系统透过挂载的信息可以找到挂载点的 inode 号码(通常一个 文件系统 的最顶层 inode 号码会由 2 号开始),此时就能够得到根目录的 inode 内容,并依据该 inode 读取根目录的 block 内的文件名数据,再一层一层的往下读。
现以查看 a.txt 文件内容为例,说明在文件系统是如何查看文件内容的:
① 透过挂载点的信息找到 inode 号码为 2 的根目录 inode,根据 inode 的访问权限判断是否可以读取该 block 的内容 ;
② 从inode中取得 block 的号码,并找到该内容有 tmp/ 目录的 inode 号码 (131098);
③ 根据 tmp/ 目录文件对应的 inode 号码 (131098) 找到 tmp/ 目录文件对应 Block 数据块
④ 从 tmp/ 目录文件对应的 Block 块中找出 a.txt 文件对应的 inode 号码 (131101)
⑤ 从 a.txt 文件对应的 inode 信息 中找到对应的 Block 块
⑥ 读出 a.txt 文件对应的 Block 块中的数据(this is a.txt file)
七、 软硬方式链接
在Windows系统中,快捷方式就是指向原始文件的一个链接文件,可以让用户从不同的位置来访问原始的文件;原文件一旦被删除或剪切到其他地方,会导致链接文件失效。但是,这个看似简单的东西在Linux系统中可不太一样。Linux系统中存在软链接和硬链接两种不同的类型。
软链接(soft link):也叫符号链接(symbolic link),仅仅包含所链接文件的名称和路径,很像一个记录地址的标签。当原始文件被删除或移动后,新的链接文件也会随之失效,不能被访问。可以针对文件、目录设置软链接,跨文件系统进行链接也不是问题。从这一点来看,它与Windows系统的“快捷方式”具有一样的性质。(可以通过readlink查看其指向)
硬链接(hard link):可以将它理解为一个“指向原始文件block的指针”,系统会创建出一个与原来一模一样的inode信息块。所以,硬链接文件与原始文件其实是一模一样的,只是名字不同。每添加一个硬链接,该文件的inode个数就会增加1;而且只有当该文件的inode个数为0时,才算彻底将它删除。换言之,由于硬链接实际上是指向原文件block的指针,因此即便原始文件被删除,依然可以通过硬链接文件来访问。需要注意的是,由于技术的局限性,不能跨分区对目录文件进行硬链接。
【注意】目录文件的"链接数"。创建目录时,默认会生成两个目录项:"."和".."。前者的inode号码就是当前目录的inode号码,等同于当前目录的"硬链接";后者的inode号码就是当前目录的父目录的inode号码,等同于父目录的"硬链接"。所以,任何一个目录的"硬链接"总数,总是等于2加上它的子目录总数(含隐藏目录)。是不能对目录做硬链接。
Linux 命令创建文件的软硬链接ln(全称“link”)
语法格式:
ln [参数] 原始文件名 链接文件名
参数:
创建软链接示例:
由上图可知,新创建的软链接文件test_softlink.txt和test.txt文件内容是一致的,但是两个文件对应的inode号码是不一样的。
当删掉原始文件test.txt 后,软链接文件test_softlink.txt立刻就无法读取了。
创建硬链接示例:
由上图可以看到,源文件与目标文件的inode号码相同,都指向同一个inode,硬链接数变成了2(这表示的是文件的inode信息块的数量变为2),test_hardlink.txt类型也成为了普通文件。
删除源文件test.txt,后仍然可以打开test_hardlink.txt文件。
删除一个文件名test.txt,使得inode节点中的"链接数"减1(仅仅删除了一个指向真实文件的指针而已)。但是它的链接数并没有减为0,所以这个文件数据块并没有删除。
参考链接:
(1) Inode与block详解【图文】_moakia_51CTO博客
(2)理解 Linux 中的 inodes - Linux开发那些事儿 - 博客园 (cnblogs.com)
(3)Linux inode 详解 - LinSenGeGe - 博客园 (cnblogs.com)
(4)存储管理:Linux中磁盘的管理(分区、格式化、挂载)、LVM_wangxu_190的博客-CSDN博客
(5)Linux文件系统(inode、block……) - xumenger - 博客园 (cnblogs.com)
以上是关于Linux文件系统与硬盘存储(分区格式化挂载inode软链接与硬链接)的主要内容,如果未能解决你的问题,请参考以下文章