文件系统是操作系统用于明确存储设备或分区上的文件的方法 和数据结构 ; 即在存储设备上组织文件的方法。操作系统中负 责管理和存储文件信息的软件结构称为文件管理系统 , 简称文件系统。 简单来说 , 它负责三件事

把存储设备上的"块" → 组织成"文件和目录" → 提供统一的读写/管理接口

从系统角度来看 , 文件系统是对文件存储设备的空间进行组织 和分配 , 负责文件存储并对存入的文件进行保护和检索的系统 。具体地说 , 它负责为用户建立文件 , 存入、读出、修改、转 储文件 , 控制文件的存取 , 安全控制 , 日志 , 压缩 , 加密等。

查看当前系统支持的文件系统

​
cat /proc/filesystems
# 或查看内核模块目录
ls /lib/modules/$(uname -r)/kernel/fs
  • 文件系统类型

    • Linux文件系统 : ext2(Extended file system), ext3, ext4, xfs(SGI), btrfs(Oracle), reiserfs, jfs(AIX), swap

    • 光盘: iso9660

    • Windows : FAT32, exFAT,NTFS

    • Unix: FFS(fast), UFS(unix), JFS2

    • 网络文件系统 : NFS, CIFS

    • 集群文件系统 : GFS2, OCFS2(oracle)

    • 分布式文件系统 : fastdfs,ceph, moosefs, mogilefs, glusterfs, Lustre

    • RAW : 未经处理或者未经格式化产生的文件系统

1. 目录层次结构(FHS 标准)

与 Windows 的"多根"结构(C:、D:、E: 盘)不同 , Linux 采用单根树形结构 , 所有文件和目录都从根目录 / 开始 , 硬盘分区、U 盘等都必须挂载到树上的某个挂载点才能访问

/
├── bin     基础用户命令 ( ls、cp、cat、mv )  , 所有用户可用
├── sbin    系统管理命令 ( fdisk、fsck、shutdown、mkfs )  , 需 root
├── boot    内核映像与引导程序 ( vmlinuz、initramfs、GRUB ) 
├── dev     设备文件 ( /dev/sda 硬盘、/dev/null 黑洞设备 ) 
├── etc     系统配置文件 ( fstab、passwd、hostname ) 
├── home    普通用户家目录 ( /home/username ) 
├── root    root 用户家目录 ( 位于根下 , 单用户模式也可访问 ) 
├── lib     共享库与内核模块 ( 现代系统常软链到 /usr/lib ) 
├── media   可移动设备自动挂载点 ( U 盘、光盘 ) 
├── mnt     临时手动挂载点
├── opt     第三方独立软件 ( /opt/google/chrome ) 
├── proc    虚拟文件系统 : 内核与进程运行时信息 ( /proc/cpuinfo ) 
├── sys     虚拟文件系统 : 设备与内核配置视图
├── run     运行时数据 ( PID、socket )  , tmpfs , 重启清空
├── tmp     临时文件 , 重启清空
├── usr     用户程序与数据 ( Unix System Resources ) 
├── var     可变数据 ( 日志 /var/log、缓存、数据库 ) 
└── lost+found  fsck 修复找回的文件存放处

FHS 标准的分类思想——按"可共享性"和"是否可变"划分

静态 ( 不变 )

可变 ( dynamic )

可共享

/usr、/opt

/var/mail

不可共享

/etc、/boot

/var/run、/home

根目录磁盘空间绝对不可耗尽 , 否则系统无法启动、无法创建新文件、服务崩溃

2. 一切皆文件

在 Linux 中 , 普通文本、目录、设备、进程、网络套接字都以"文件"的方式统一管理

ls -l 第一列标识文件类型

-   普通文件
d   目录
l   符号链接 ( 软链接 ) 
b   块设备 ( 硬盘 , /dev/sda ) 
c   字符设备 ( /dev/tty、/dev/null ) 
p   命名管道
s   套接字
  • 块设备 : 按块随机读写(硬盘、SSD)

  • 字符设备 : 按字节流读写(键盘、串口)

3. inode : 文件的"身份证"

3.1. inode基础

inode(Index Node , 索引节点 ) 是文件的唯一标识 , 记录文件的元数据。

  • 文件类型(普通文件、目录、链接等)

  • 权限(rwx)、所有者(UID/GID)

  • 大小、时间戳(atime、mtime、ctime)

  • 链接计数

  • 指向数据块的指针(ext4 中为小文件做了内联优化 , 可把很小的文件直接放进inode)

ls -i filename      # 查看 inode 号
stat filename       # 查看详细 inode 信息

关键: 文件名不存储在 inode 中! 文件名与 inode 的映射关系由目录项(dentry)维护

inode 面试题
1. 一个100M的磁盘分区 , 写入1K的文件或写入1M的文件 , 分别可以写入多少个?
​
分析 : 换算单位100M=1024000K  , 1M=1024K 一个block=4K
​
如果写入1K的文件 , 由于1K的文件远小于1个block的大小 , 1个block就可以存一个1K的文件 , 所以1024000/4=25600 个文件.
​
如果写入1M的文件 , 优于1M的文件远大于1个block的大小 , 1个block存不下一个1M的文件 , 
因此 , 1M的文件需要1024/4=256个block块来存1M的文件 , 所以100M的空间最多能存1024000/256=400个文件.
​
2. 假设你的Ext4文件系统使用 4K block  , 而该文件系统中有 10000 个小文件 , 每个文件大小均为 50bytes ,  请问此时你的磁盘浪费多少容量?
​
分析 : 单位换算 , 一个block大小为 4K=4096 bytes 远大于一个文件的大小50bytes
​
因此一个block就浪费了 4096-50=4046 , 10000个文件就浪费10000*4046=40460000bytes
换算单位 : 浪费了38M左右的容量

3.2 dentry / inode / 数据块的关系

文件名(dentry) ──► inode号 ──► inode ( 元数据+块指针 )  ──► 数据块(block)
  • 文件名 : 保存在磁盘目录项中

  • dentry : VFS 在内存中维护的路径组件和查找缓存

  • inode :代表文件系统对象 , 保存元数据与数据映射

4. block : 存放数据的地方

4.1 block基础

  • block 是存放文件内容数据的地方 , ext 系列支持 1K /2K /4K 三种 , 格式化后不可更改

  • 文件太大 → 占用多个 block ; 文件小于 block → 剩余容量浪费

磁盘布局(以 ext 系列为例)

[ 超级块 superblock ] [ inode 区 ] [ 数据块区 ] [ 块位图/inode位图 ]
  • 超级块 : 记录文件系统整体信息——块大小、inode 数、空闲块数、挂载状态 , 通常有多个备份副本 ( 块偏移 8193、16385、24577… )

  • inode 区 : 保存 inode

  • 数据块区 : 保存文件实际内容

  • 位图 : 标记哪些块/inode 已使用

inode与block的关系

  • inode:记录文件的属性 , 一个文件占用一个inode , 同时记录此文件的数据所在的 block 号码 ; 由于实际中inode号与文件名分开存储 。

  • block : 是用来放置文件内容数据地地方 , 若文件太大时 , 会占用多个 block 。在 Ext2+文件系统中所支持的block大小有1K,2K及4K三种而已。在格式化时block的大小就固定了 , 且每个 block 都有编号 , 以方便 inode 的记录。 block有一下注意点。

    • block 的大小与数量在格式化完就不能够再改变了(除非重新格式化) ;

    • 每个 block 内最多只能够放置一个文件的数据 ;

    • 如果文件大于 block 的大小 , 则一个文件会占用多个 block 数量 ;

    • 如果文件小于 block , 则该 block的剩余容量就不能够再被使用了(磁盘空间会浪费)

注:

block越大 , inode越少 , 适合存储大文件的文件系统 ; block越小 , inode越多 , 适合存储文件多而小的文件系统。 系统运行时 , inode和block会在修改后内存与磁盘做一个同步 , 我们用ls -li列出来的内容这是内存中的暂存 , 所以有时候系统非正常的关机会导致block和inode的不同步问题。

4.2 超级块(superblock)

超级块是文件系统特性的记录 , 包括其大小 , 块大小 , 空块和填充块及其各自的计数 , inode表的大小和位置 , 磁盘块映射和使用信息 , 以及 块组的大小。

一个EXT2文件系统时 , 基本的Linux文件系统的类型 , 分为块组 , 其中每个都包含 , 默认情况下 , 8192个块。同一文件系统上的默认块大小为4096 字节。因此 , 在块偏移8193,16385,24577等处存在超级块的备份副本。

可以通过dumpe2fs 查看对应的文件系统超级块信息。 centos6超级块组中有 8193个超级块, centos7 有32768个 超级块大小

dumpe2fs
-h : 查看超级块信息 , 不显示分组信息 

在超级块数据有所丢失时 , 可以通过以下命令可以通过备份块回复超级块。

e2fsck -f -b 8193 /dev/hda2
superblock
dd if=/dev/zero of=/dev/sdb1 bs=1M count=10
e2fsck -f -b 24577  /dev/sdb1
或者 fsck -a /dev/sdb1

使用fsck会直接调用e2fsck命令

5. VFS

Linux 支持 ext4、XFS、Btrfs、tmpfs、procfs、NFS 等众多文件系统。用户程序不可能为每种文件系统写一套 open_ext4()、open_xfs()——VFS ( Virtual File System ) 就是中间的抽象层。在大部分情况下 , 用户通过libc和kernel的VFS交互 , 不需要关心底层文件系统的具体实现。

vfs的作用。 vfs所隐含的思想是把表示很多不同种类文件系统的共同信息放入内核 ; 其中有一个字段或函数来支持Linux所支持的所有实际文件系统所提供的任何操作。对所调用的每个读、写或其他函数 , 内核都能把它们替换成支持本地Linux文件系统、NTFS文件系统 , 或者文件所在的任何其他文件系统的实际函数。有了vfs , 就能很容易实现不同文件系统之间的数据读写 , 因为它们对外接口都是一样的 , 都是vfs导出的通用接口。

linuxVFS
应用程序 : open() / read() / write()
        │   ( 统一接口 ) 
        ▼
┌─ VFS 层 ( 内核 ) ────────────────┐
│  4 个核心对象 :                  │
│  superblock  已挂载的文件系统    │
│  inode       一个文件对象       │
│  dentry      路径目录项缓存     │
│  file        一次打开的对象(fd) │
└───────────────────────────────┘
        │  转发给具体实现
        ▼
  ext4 / XFS / Btrfs / NFS / ...

内核把每个读写请求替换成支持本地 ext4、NTFS 或任何其他文件系统的实际函数 , 差异被完全屏蔽在下层 。所以 cat /proc/cpuinfo、cat /var/log/app.log、读 NFS 上的文件 , 用的是完全相同的用户态接口。

6. 日志(Journal)机制

按是否支持日志分类:

类型

代表

特点

日志型

ext3、ext4、xfs

先写日志再写数据 , 崩溃后按日志重做/回滚 , 恢复快

非日志型

ext2、vfat

崩溃后需全量扫描检查(fsck) , 慢且可能丢数据

三种日志模式(ext3/4)

  • journal : 元数据+数据都先写日志 , 最安全最慢

  • ordered(默认) : 元数据写日志 , 数据先落盘再写元数据

  • writeback : 只日志元数据 , 最快但可能损坏刚写的数据

7. 创建文件系统

在centos6中默认使用ext4文件系统 , 在centos7中默认使用xfs文件件系统。一般使用mkfs这个命令创建文件系统

在cenos6安装系统后 , 手工分区ext文件系统无acl功能。需要通过tune2fs -o acl 添加对应的ACL功能

7.1 基础命令

7.1.1 mkfs

mkfs(make filesystem) 用于在块设备(分区、LVM、整个磁盘、loop 设备、RAID 设备)上创建文件系统 , 也就是通常所说的"格式化"。 它是 Linux 的通用入口命令 : 本身不实现具体的文件系统逻辑 , 而是根据 -t 指定的类型 , 调用对应的前端工具完成实际工作 :

mkfs -t ext4 /dev/sdb1
        │
        ▼
实际执行的是 ──► /usr/sbin/mkfs.ext4
                    │
                    ▼
                  ext4 真正由 mke2fs 实现
ls /usr/sbin/mkfs*     # 查看系统支持哪些 mkfs 前端
# mkfs.btrfs  mkfs.ext2  mkfs.ext3  mkfs.ext4  mkfs.fat
# mkfs.minix  mkfs.msdos  mkfs.vfat  mkfs.xfs  mkfs.ntfs ...

  • 语法 : mkfs [OPTIONS] [-t type] [fs-options] device [size]

    • device : 预备检查的硬盘分区 , 例如 : /dev/sda1

    • -V : 详细显示模式

    • -t : 给定档案系统的型式 , Linux 的预设值为 ext2 同mkfs.type 如mkfs.xfs

    • -c : 在制做档案系统前 , 检查该partition 是否有坏轨

    • -l bad\_blocks\_file : 将有坏轨的block资料加到 bad_blocks_file 里面

    • block : 给定 block 的大小

    • -L "Lable" : 设置卷标

7.1.2 mke2fs

mke2fs(make ext2 filesystem ) 用于在设备(分区、磁盘、镜像文件等) 上创建 ext2/ext3/ext4 文件系统。它是 mkfs.ext2、mkfs.ext3、mkfs.ext4 命令的底层实现 , 这几个命令实际上是 mke2fs 的硬链接。

一个文件需要占用一个inode , 同时至少占用一个块。

  • 语法:

    mke2fs [选项] 设备 [块数]
    mke2fs -t ext4 /dev/sdb1          # 最常用的形式
  • 选项

    选项

    说明

    -t fs-type

    指定文件系统类型 : ext2 / ext3 / ext4 ( 默认 ext2 , 强烈建议显式指定 )

    -b block-size

    块大小 , 取值为 1024 / 2048 / 4096 ( 字节 ) , 默认根据分区大小自动选择

    -c

    格式化前检查坏块 ( -c -c 执行读写测试 , 更彻底但更慢 )

    -C cluster-size

    指定簇大小 ( bigalloc 特性 , 适合海量小文件或大文件场景 )

    -E opts

    扩展选项 , 如 stride=32,stripe-width=64 ( 对齐 RAID 条带 )

    -i bytes-per-inode

    每多少字节分配一个 inode , 决定 inode 总数。默认约 16KB/inode

    -N num

    直接指定 inode 数量

    -I inode-size

    inode 大小 : 128 / 256 / 512 / 1024 / 2048 , ext4 默认 256

    -j

    创建带日志的文件系统 ( 即 ext3 )

    -J size=N

    指定日志大小 ( 单位 MB )

    -L label

    设置卷标

    -m percent

    为超级用户保留的块比例 , 默认 5% , 数据盘建议设为 0 或 1

    -O feature

    启用/禁用文件系统特性 ( 加 ^ 前缀表示禁用 )

    -U uuid

    设置 UUID , 可填 random、time、clear 或具体 UUID

    -S

    只重写超级块和组描述符 ( 用于超级块损坏后的急救 )

    -n

    演练模式 , 只显示将要执行的操作 , 不实际写入

    -F

    强制在普通文件或整个磁盘设备上创建

    -q / -v

    静默模式 / 详细模式

    -V

    显示版本信息

  • 常用-O 特性(ext4相关)

    has_journal      # 日志 ( ext3/ext4 必备  )
    extents          # extent 树 ( ext4 核心 , 替代传统块映射  )
    dir_index        # 目录索引 , 加速大目录查找
    resize_inode     # 支持在线扩容
    64bit            # 支持超大文件系统
    huge_file        # 支持 >2TB 的单个文件
    flex_bg          # 灵活的块组布局
    metadata_csum    # 元数据校验和
    ^has_journal     # 禁用日志 ( 即 ext2  )

    使用-O ^FEATURE关闭指定特性

7.1.3 tune2fs

tune2fs 用于调整已存在的 ext2/ext3/ext4 文件系统的可调参数 , 无需重新格式化。它可以查看/修改卷标、UUID、保留空间、挂载计数、文件系统特性、默认挂载选项等。

  • 语法 :

    tune2fs [选项] 设备
    tune2fs -l /dev/sdb1                     # 查看文件系统信息 ( 最常用  )
  • 选项

    • -l : 查看指定文件系统超级块信息 ;

    • -L 'LABEL' : 修改卷标

    • -m # : 修预留给管理员的空间百分比

    • -j : 将ext2升级为ext3

    • -O : 文件系统属性启用或禁用(, –O ^has_journal)

      tune2fs -O ^has_journal /dev/sdb1      # 去掉日志 ( 变成 ext2  )
      tune2fs -O has_journal /dev/sdb1       # 补加日志 ( 变成 ext3  )
      tune2fs -O dir_index /dev/sdb1         # 启用目录索引
      tune2fs -O ^resize_inode /dev/sdb1     # 禁用在线扩容能力

    • -o: 调整文件系统的默认挂载选项 ,(禁用: –o ^acl)

    • -U UUID : 修改UUID号

示例:

# 1. 查看文件系统当前状态
tune2fs -l /dev/sdb1 | head -20

# 2. 克隆盘后修改 UUID ( 避免冲突  )
tune2fs -U random /dev/sdc1

# 3. 数据盘:取消保留空间 + 关闭定期 fsck
tune2fs -m 0 -c 0 -i 0 /dev/sdb1

# 4. ext2 无损升级为 ext3
tune2fs -j /dev/sdb1

# 5. 高危操作前生成撤销文件
tune2fs -E undo_file=/root/sdb1.undo -O ^has_journal /dev/sdb1
# 后悔时用:e2undo /root/sdb1.undo /dev/sdb1

# 6. 修正错误的最后挂载点记录
tune2fs -M /data /dev/sdb1

7.1.4 findfs

findfs 用于按卷标 ( LABEL )或UUID 在系统中查找文件系统所在的设备节点 , 是 e2fsprogs 工具包中的一员。它的作用很简单但非常实用:返回 /dev/xxx 这样的设备路径。

  • 语法:

    findfs [options] LABEL=<label>  
    findfs [options] UUID=<uuid> 

示例:

# 查找成功
$ findfs LABEL=data
/dev/sdb1

# 查找失败 ( 退出码 1  )
$ findfs UUID=12345678-1234-1234-1234-123456789abc
findfs: unable to resolve 'UUID=12345678-...'

# 1. 按卷标查找设备
findfs LABEL=root
# 输出:/dev/mapper/vg0-root

# 2. 按 UUID 查找设备
findfs UUID=3f5c8a2b-9d1e-4f7a-b2c5-8e9d0a1b2c3d
# 输出:/dev/nvme0n1p2

# 3. 在脚本中配合挂载使用
mount "$(findfs LABEL=data)" /mnt/data

# 4. 脚本中判断是否找到 ( 利用退出码  )
if findfs LABEL=backup >/dev/null 2>&1; then
    echo "找到备份盘"
else
    echo "未找到备份盘"
fi

7.1.5 e2label

e2label 用于显示或修改 ext2/ext3/ext4 文件系统的卷标()Volume Label) ,属于 e2fsprogs 工具包。功能上完全等价于 tune2fs -L , 但语法更简单。

e2label device [ new-label ] 修改ext文件系统卷标 

示例:

显示卷标

$ e2label /dev/sda1
rootfs

$ e2label /dev/sdb1
#  ( 无输出 = 该设备没有设置卷标  )

等价查看方式:

tune2fs -l /dev/sdb1 | grep "filesystem volume name"
blkid /dev/sdb1
lsblk -o NAME,LABEL

设置/修改卷标

# 设置卷标
e2label /dev/sdb1 data

# 修改已有卷标 ( 直接覆盖  )
e2label /dev/sdb1 backup

# 清除卷标
e2label /dev/sdb1 ""

7.2 文件系统修复

7.2.1 e2fsck

文件系统修复的核心工具是 e2fsck(ext2/3/4) , 但完整的能力体系还包括: 事前预防(巡检策略)、事中评估(只读检查)、事后恢复(备份超级块、debugfs 数据抢救)。

  • 语法

    e2fsck [选项] 设备
  • 运行模式

    选项

    模式

    说明

    -p

    preen 自动模式

    只修复"安全"的错误 , 遇到需要人工判断的问题就跳过并退出码 4。开机自动检查用的就是它

    -y

    全自动修复

    对所有问题回答 yes , 适合无人值守。⚠️ 严重损坏时可能越修越糟

    -n

    只读检查

    对所有问题回答 no , 不修改任何数据。修复前先用它评估损伤

    无选项

    交互模式

    逐条询问 , 适合重要数据

    -c

    坏块扫描

    结合 fsck 扫描坏块(大容量盘很慢 , 可配合 -C 0 看进度)

    重要数据 → 先 -n 评估 → 用 e2image 备份元数据 → 再交互或 -y 修复。

    退出码

    退出码

    含义

    0

    没有错误

    1

    错误已修复

    2

    错误已修复 , 但需要重启

    4

    存在未修复的错误 ( preen 模式遇到危险问题 )

    8

    操作错误 ( 内存不足、设备不存在等 )

    16

    用法错误

    32

    被用户取消 ( Ctrl+C )

    128

    共享库错误

  • 重要选项

    选项

    说明

    -f

    强制检查 ( 即使文件系统标记为 clean )。日常排查必加

    -b 块号

    使用备份超级块修复 ( 超级块损坏时的救命选项 )

    -B 块大小

    指定块大小 ( 配合 -b 时可能需要 )

    -j 外部日志设备

    指定外部日志位置

    -k

    保留已有坏块列表 ( 配合 -c )

    -l 文件 / -L 文件

    从文件导入坏块列表 / 替换坏块列表

    -D

    优化目录结构 ( 重组 htree 索引 )

    -E help

    查看扩展选项 ( 如 journal_only、fragcheck )

    -E journal_only

    只回放日志 ( 日志损坏时慎用 )

    -z undo_file

    生成撤销文件 , 修错了可用 e2undo 回滚

    -C 0

    把进度条输出到 stdout

    -v

    详细模式

  • 五阶段检查流程

    e2fsck 的修复按固定阶段执行 , 看懂输出日志能判断损坏程度:

    Pass 1: 检查 inode、块、大小        ← 数据块级损坏
    Pass 1D: 检查目录洞 ( dir_index  )
    Pass 1E: 检查扩展属性
    Pass 2: 检查目录结构              ← 目录项损坏
    Pass 3: 检查目录连接性 ( / 可达性  )
    Pass 4: 检查引用计数              ← 硬链接计数错误
    Pass 5: 检查组概要信息            ← 位图不一致
  • 典型输出与处理

    元数据不一致 , 一般可放心修复 ( y )

    Inode 123456, i_blocks is 256, should be 248.  Fix<y>?

    块位图错误 , 修复 ( y )

    Block bitmap differences: +12345 ... Fix<y>?

    孤儿 inode , 修复后文件会出现在 lost+found 目录 , 文件名丢失但数据可能还在

    Unattached inode 234567 ... Connect to /lost+found<y>?

  • 标准修复流程

    场景一: 普通数据分区

    # 1. 卸载(必须!挂载状态修复是数据灾难的头号原因)
    umount /dev/sdb1
    
    # 2. 先看磁盘底层有没有坏(可选)
    badblocks -sv /dev/sdb1        # 只读扫描
    # 或合并到 fsck:e2fsck -c -f /dev/sdb1
    
    # 3. 只读评估损伤(可选但强烈建议)
    e2fsck -n -f /dev/sdb1
    
    # 4. 备份关键元数据(有重要数据时)
    e2image -r /dev/sdb1 /root/sdb1.meta    # -r 只备份元数据 , 很小
    
    # 5. 正式修复(带撤销保险)
    e2fsck -f -y -z /root/sdb1.undo /dev/sdb1
    
    # 6. 检查退出码 , 确认修复完成
    echo $?
    
    # 7. 挂载后检查抢救出来的文件
    mount /dev/sdb1 /mnt/data
    ls /mnt/data/lost+found/

    场景 2 : 根文件系统损坏(系统无法正常启动)

    # 方法 A:强制开机自检(能进系统但怀疑有问题)
    touch /forcefsck          # 根分区所在系统
    reboot
    # 开机时 systemd-fsck / e2fsck -p 会自动检查
    
    # 方法 B:从救援模式修复
    # 1. 重启进 GRUB → 按 e 编辑启动项 → 在 linux 行尾加:
    systemd.unit=rescue.target
    # 2. 进入后根分区只读挂载 , 直接执行:
    e2fsck -f /dev/mapper/vg0-root
    
    # 方法 C:用 Live CD / 安装盘 rescue 模式
    # 挂载原系统分区后修复 , 注意别修错设备

    场景 3: 超级块损坏(报 "bad magic number")

    e2fsck /dev/sdb1
    # e2fsck: Superblock invalid, trying backup blocks...
    # 自动尝试备份超级块失败时手动来:
    
    # 1. 找备份超级块位置(不要真的格式化 , -n 是演练)
    mke2fs -n /dev/sdb1
    # Superblock backups stored on blocks: 
    #     32768, 98304, 163840, 229376, 294912, ...
    
    # 2. 用备份超级块修复(块大小通常 4096)
    e2fsck -b 32768 -B 4096 /dev/sdb1
    
    # 3. 还不行就逐个尝试后面的备份块 , 或用 debugfs 查看
    debugfs -b 32768 /dev/sdb1

    场景 4 : 只读重挂载(errors=remount-ro 触发)

    这是内核检测到文件系统错误后的自我保护 , dmesg 会有 EXT4-fs error。处理:

    # 1. 确认是哪个设备
    findmnt / -o SOURCE,FSTYPE
    dmesg | grep EXT4-fs
    ​
    # 2. 尽快卸载(能 umount 就 umount;不能就停业务后 umount)
    umount /dev/sda1
    ​
    # 3. 修复
    e2fsck -f /dev/sda1
    ​
    # 4. 查明根因(常见:磁盘坏道、RAID 掉盘、内存故障、掉电)
    smartctl -a /dev/sda

7.2.2 fsck

fsck(file system check)是Linux 文件系统检查的前端调度程序(wrapper)。它本身不执行具体检查 , 而是根据文件系统类型调用对应的底层工具——检查 ext4 时实际执行的是 e2fsck , 检查 xfs 时调用 xfs_repair。

你执行:        fsck -y /dev/sdb1
实际运行:      /sbin/fsck.ext4 -y /dev/sdb1  →  e2fsck -y /dev/sdb1
  • 语法 : fsck [选项] [文件系统...]

    文件系统参数可以是设备(/dev/sdb1)或挂载点(/data , 会去 fstab 中查对应设备)。

  • 常用选项

    作用范围控制

    选项

    说明

    -A

    检查 /etc/fstab 中所有设置了 pass 编号的文件系统(开机自检就是用它)

    -R

    配合 -A , 跳过根文件系统

    -P

    配合 -A , 根文件系统与其他分区并行检查(默认根先单独查完)

    -t 类型

    只检查指定类型 , 如 -t ext4;逗号分隔多个;前缀 no 排除 , 如 -t noxfs

    -M

    跳过已挂载的文件系统(防止误修 ,推荐配合 -A)

    -s

    串行检查所有文件系统(默认同类型并行、单盘串行)

    -l

    对整盘加文件锁 , 多块盘检查时可安全并行(传统 init 脚本防冲突用)

    执行方式控制

    选项

    说明

    -p / -a

    preen 自动模式:只修复安全错误 , 遇到危险问题跳过(开机默认模式)

    -y

    全部回答 yes(透传给 e2fsck 等)

    -n

    全部回答 no , 只读检查

    -r

    交互式逐项询问

    -C 0

    显示进度条(透传给 e2fsck)

    调试与显示

    选项

    说明

    -N

    不执行 , 只显示将要运行什么命令(排错必用)

    -V

    显示实际执行的命令和详细过程

    -T

    不打印标题信息(配合 -A 静默输出)

    -D

    调试输出

fstab 每行最后两列控制 fsck 行为 :

/dev/sdb1   /data   ext4   defaults   0   2
                                    ↑dump  ↑pass

pass 值

含义

0

永不检查(swap、proc、xfs、btrfs 通常为0)

1

根分区 , 最先检查

2

其他分区 , pass 为 1 的检查完后并行检查

示例:

日常检查单块盘

umount /dev/sdb1
fsck /dev/sdb1              # 自动识别类型 , 调用 e2fsck
fsck -t ext4 /dev/sdb1      # 显式指定类型(探测失败时用)

修复模式

fsck -y /dev/sdb1           # 全自动修复(数据不重要时)
fsck -n /dev/sdb1           # 只读评估(数据重要时 , 先评估再决定)
fsck -r /dev/sdb1           # 交互式

批量检查

fsck -A                     # 按 fstab 全量检查(开机逻辑)
fsck -AR                    # 检查除根分区外的所有分区
fsck -A -M -T               # 跳过已挂载的 , 静默批量巡检

进度显示

fsck -C 0 /dev/sdb1         # 进度条输出到终端(大容量盘必备)

开机自检的现代机制

时代

机制

SysV init

init 脚本直接运行 fsck -a -A ; /forcefsck 文件强制全查 , /fastboot 跳过检查

systemd

systemd-fsck-root.service(查根分区)+ systemd-fsck@.service(查其他分区) , 在挂载之前运行 , 相当于 fsck -p


熊熊