一、什么是文件系统

操作系统中用于管理和组织磁盘设备上文件的方法和数据结构叫做文件系统.

1.1 根文件系统(rootfs):

在Linux中, 文件系统和倒树形结构一样, 位于最顶层的的一个分区我们称之为根(root), 用于安装linux系统, 类似于Windos的系统盘; 根分区又叫做根文件系统(root filesystem).
根文件系统由内核在启动的时候装载(之装载根分区, 其他分区由mount命令进行装载).

1.2 挂载(mount)概念

挂载可以理解为给一个磁盘分区创建一个入口(Mount Point)并与之关联起来让用户能够访问分区中的类容的行为或动作, 访问入口类似与Windows的盘符C:\、D:\等.
分区挂载

解除这个关联关系的过程称为卸载.

1.3、FHS(FileSystem Heirache Strandard)

由于Linux有众多的发行版, 为了保证每个发行版中文件系统的一致性, FHS定义了Liunx发行版的目录结构和目录内容, FHS由Linux Foundation维护, 最新版本3.0发布于2015年6月; 下列是节选. 详细请参见FHS

  • /boot: 引导文件存放目录, 内核文件(vmlinuz)、引导加载器(bootloader, grub)都存放于此目录;
  • /bin: 供所有用户使用的基本命令, 不能关联至独立分区, OS启动即会用到的命令;
  • /sbin: 管理类的基本命令, 不能关联至独立分区, OS启动即会用到的命令, 供系统管理员(root);
  • /lib: 基本共享库文件, 以及内核模块文件(/lib/modules);
  • /lib64: 专用于x86_64系统上的辅助共享库文件存放位置;
  • /etc: 配置文件目录(纯文本文件);
  • /home/USERNAME: 普通用户的家目录;
  • /root: 管理员的家目录;
  • /media: 便携式移动设备挂载点;
  • /mnt: 临时文件系统挂载点;
  • /dev: 设备文件及特殊文件存放位置;
  • /opt: 第三方应用程序的安装位置;
  • /srv: 系统上运行的服务用到的数据;
  • /tmp: 临时文件存放位置;
  • /usr: universal shared, read-only data;
    • bin: 保证系统拥有完整功能而提供的应用程序;
    • sbin: 保证系统拥有完整功能而提供的应用程序, 只有管理员有权限运行;
    • lib:
    • lib64:
    • include: C程序的头文件(header files)存放位置;
    • share: 结构化独立的数据, 例如doc, man等;
    • local: 取代/opt的第三方应用程序的安装位置;
      bin, sbin, lib, lib64, etc, share
  • /var: variable data files;
    • cache: 应用程序缓存数据目录;
    • lib: 应用程序状态信息数据;
    • local: 专用于为/usr/local下的应用程序存储可变数据;
    • lock: 锁文件
    • log: 日志目录及文件存放目录;
    • opt: 专用于为/opt下的应用程序存储可变数据;
    • run: 运行中的进程相关的数据, 通常用于存放进程的PID文件;
    • spool: 应用程序数据池;
    • tmp: 保存系统两次重启之间产生的临时数据;
  • /proc: 用于输出内核和进程信息相关的虚拟文件系统;
  • /sys: 用于输出当前系统上硬件设备相关信息的虚拟文件系统;
  • /selinux: security enhanced Linux, selinux相关的安全策略等信息的存储位置;

二、Linux下的文件类型

Linux系统中一切皆文件, 常见的文件类型有:

- (f): 普通文件  
d: 目录文件
b: 块设备
c: 字符设备
l: 符号链接文件(软连接)
p: 管道文件
s: 套接字文件, socket

三、文件系统类型

  • Linux支持如下文件系统:
    • ext系列: ext2~4
    • xfs
    • btrfs
    • reiserfs
    • jfs
    • swap: 交换分区使用
  • Windows下文件系统
    • fat32
    • NTFS
  • Unix下文件系统
    • FFS
    • UFS
    • JFS2
  • 网络文件系统
    • NFS
    • CIFS
  • 集群文件系统
    • GFS2
    • OCFS2
  • 分布式文件系统
    • ceph
    • moosefs
    • mogilefs
    • GlusterFS
    • lustre
  • 根据其是否支持“journal”功能
    • 日志型文件系统: ext3, ext4, xfs, ...
    • 非日志型文件系统: ext2, vfat

四、文件系统的组成部分

文件系统由两部分组成, 一是内核中的模块, 二是管理文件系统的工具.

4.1 文件系统作为内核模块的管理方法

作为内核中的模块可以使用lsmod进行查看, 将一个新的文件系统作为一个模块添加进内核使用modprobe命令, 示例如下:

# lsmod: 显示Linux内核模块的状态
[root@zabbix ~]# lsmod | grep xfs
xfs                   939662  2 
libcrc32c              12644  1 xfs
[root@zabbix ~]# lsmod | grep ext4
# 没有查找到ext4, 可以通过modprobe将ext4文件系统装载至内核模块

# modprobe: 添加一个模块至Linux内核或者从内核中删除一个模块
# modprobe -a ModulName: 通过命令行将模块插入内容
[root@zabbix ~]# modprobe -a ext4
[root@zabbix ~]# lsmod | grep "ext4"
ext4                  578819  0 
mbcache                14958  1 ext4
jbd2                  102940  1 ext4

# modprobe -r ModulName: 从内核中删除一个模块, 如果此模块有依赖的模块并且没有被使用, 会尝试一起删除.
[root@zabbix ~]# modprobe -r ext4
[root@zabbix ~]# lsmod | grep "ext4"

五、Linux的虚拟文件系统(VFS)

Linux系统下存在很多文件系统, 有些时候我们会对某些文件进行跨文件系统进行操作, 但是我们在操作的时候却不需要在意文件系统的不同, 如下图所示:
跨文件系统操作

[root@zabbix ~]# df -h
Filesystem                               Size  Used Avail Use% Mounted on
/dev/mapper/centos_docker--package-root   18G  2.5G   15G  15% /
devtmpfs                                 903M     0  903M   0% /dev
tmpfs                                    913M     0  913M   0% /dev/shm
tmpfs                                    913M  8.6M  904M   1% /run
tmpfs                                    913M     0  913M   0% /sys/fs/cgroup
/dev/sda1                                497M  124M  373M  25% /boot
tmpfs                                    183M     0  183M   0% /run/user/0
/dev/sdb1                                5.0G   33M  5.0G   1% /mnt/xfs # sdb1文件系统为xfs
/dev/sdb2                                4.8G   20M  4.6G   1% /mnt/ext4 # sdb2文件系统为ext4
[root@zabbix ~]# blkid /dev/sdb1
/dev/sdb1: UUID="e8a1015b-8b58-4bba-864b-bd8973dcf7bd" TYPE="xfs" 
[root@zabbix ~]# blkid /dev/sdb2
/dev/sdb2: UUID="ae886019-79d3-4ff4-b7c4-79915a6677d8" TYPE="ext4" 

# 通过cp操作来测试跨文件系统操作
[root@zabbix ~]# cp -rf /mnt/xfs/* /mnt/ext4/
[root@zabbix ~]# ls -l /mnt/ext4/
total 24
-rw-r--r-- 1 root root   497 Dec 12 10:50 fstab
-rw-r--r-- 1 root root   233 Dec 12 10:50 hosts
drwx------ 2 root root 16384 Dec 12 10:46 lost+found
# 直接cp即可, 不需要额外的操作

为什么我们能够直接进行跨文件小系统的操作, 而不需要额外的操作呢? 这是因为有VFS(Virtual FileSystem)的原因.
VFS是Linux内核中用于对接不同文件系统的一个中间层, 通过其提供的系统调用来访问多个不同文件系统; 如下图所示:
VFS

六、文件系统相关管理命令

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

[root@zabbix ~]# cat /proc/filesystems
nodev   sysfs
nodev   rootfs
nodev   bdev
nodev   proc
nodev   cgroup
nodev   cpuset
nodev   tmpfs
nodev   devtmpfs
nodev   debugfs
nodev   securityfs
nodev   sockfs
nodev   pipefs
nodev   anon_inodefs
nodev   configfs
nodev   devpts
nodev   ramfs
nodev   hugetlbfs
nodev   autofs
nodev   pstore
nodev   mqueue
        xfs
nodev   vmhgfs
nodev   overlay
        ext3
        ext2
        ext4
        btrfs

6.1 创建文件系统(格式化)

6.1.1 mkfs命令

mkfs命令永不创建文件系统, 用法如下:

# mkfs.FS_TYPE [OPTIONS] /dev/DEVICE; FS_TYPE: ext4、xfs、btrfs、vfat、...
[root@zabbix ~]# mkfs. # 双击tab进行命令补全
mkfs.btrfs   mkfs.cramfs  mkfs.ext2    mkfs.ext3    mkfs.ext4    mkfs.minix   mkfs.xfs
[root@zabbix ~]# mkfs.xfs /dev/sdb1 
meta-data=/dev/sdb1              isize=256    agcount=4, agsize=131072 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=0        finobt=0
data     =                       bsize=4096   blocks=524288, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=0
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none      
extsz=4096   blocks=0, rtextents=0

# mkfs -t FS_TYPE /dev/DEVICE
    # -L 'LABLE': 设定卷标
[root@zabbix ~]# mkfs -t btrfs -L 'Text' /dev/sdb2
btrfs-progs v3.19.1
See http://btrfs.wiki.kernel.org for more information.

Turning ON incompat feature 'extref': increased hardlink limit per file to 65536
Turning ON incompat feature 'skinny-metadata': reduced-size metadata extent refs
fs created label Text on /dev/sdb2 # 创建的卷标
        nodesize 16384 leafsize 16384 sectorsize 4096 size 1.00GiB

[root@zabbix ~]# blkid /dev/sdb2 
/dev/sdb2: LABEL="Text" UUID="41968d5d-06db-45a9-96ff-429a836327d4" UUID_SUB="1e4c6b46-9319-48d9-8b9f-87a52f9d318e" TYPE="btrfs"

6.1.2 mke2fs命令

mke2fs命令是ext系列文件系统专用管理工具, 用法如下:

# mke2fs [OPTIONS] /dev/DEVICE
    # -t [ext2|ext3|ext4]: 指定文件系统类型
    # -b [1024|2048|4096]: 指定块大小
    # -L 'LABEL': 指定标签
    # -j: 相当于-t ext3
    # -i number: 为数据空间中每number个字节创建一个inode, 此大小不应该小于block的大小
    # -N number: 为数据空间创建number个inode
    # -m number: 为管理人员预留的空间占据的百分比
    # -O FEATURE[,...]: 启用指定特性
        # -O ^FEATURE: 关闭指定特性

6.1.3 mkswap命令

mkswap命令用于创建交换分区, 需要先在fdisk中调整分区编号为82.

# mkswap [OPTIONS] DEVICE
    # -L 'LABEL': 指定卷标
[root@zabbix ~]# mkswap -L 'swap test' /dev/sdb1 
mkswap: /dev/sdb1: warning: wiping old ext3 signature.
Setting up swapspace version 1, size = 2097148 KiB
LABEL=swap test, UUID=890bdd0b-8fbf-40a3-97f0-56779c256612

[root@zabbix ~]# blkid /dev/sdb1 
/dev/sdb1: LABEL="swap test" UUID="890bdd0b-8fbf-40a3-97f0-56779c256612" TYPE="swap"

6.2 文件系统参数查看命令

6.2.1 e2label命令

e2label用于管理ext系列文件系统的LABEL.

# e2label /dev/DEVICE [LABEL]
[root@zabbix ~]# e2label /dev/sdb1 'e2label test'
[root@zabbix ~]# e2label /dev/sdb1 
e2label test
[root@zabbix ~]# blkid /dev/sdb1 
/dev/sdb1: LABEL="e2label test" UUID="7acd54a5-4692-4cdf-b614-36e0f5920922" TYPE="ext4" 

6.2.2 tune2fs命令

tune2fs用于重新设定ext系列文件系统可调整参数的值.

# -l: 查看指定文件系统超级块信息; super block
[root@zabbix ~]# tune2fs -l /dev/sdb1 
tune2fs 1.42.9 (28-Dec-2013)
Filesystem volume name:   e2label test
Last mounted on:          <not available>
Filesystem UUID:          7acd54a5-4692-4cdf-b614-36e0f5920922
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent 64bit flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              131072
Block count:              524288
Reserved block count:     26214
Free blocks:              498132
Free inodes:              131061
First block:              0
Block size:               4096
Fragment size:            4096
Group descriptor size:    64
Reserved GDT blocks:      255
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Flex block group size:    16
Filesystem created:       Tue Dec 12 14:16:48 2017
Last mount time:          n/a
Last write time:          Tue Dec 12 14:38:37 2017
Mount count:              0
Maximum mount count:      -1
Last checked:             Tue Dec 12 14:16:48 2017
Check interval:           0 (<none>)
Lifetime writes:          65 MB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      86a040e8-d691-4239-98f0-7fbe556be1ae
Journal backup:           inode blocks

# -L 'LABEL': 修改卷标
[root@zabbix ~]# tune2fs -L 'tune2fs test' /dev/sdb1
tune2fs 1.42.9 (28-Dec-2013)
[root@zabbix ~]# blkid /dev/sdb1 
/dev/sdb1: LABEL="tune2fs test" UUID="7acd54a5-4692-4cdf-b614-36e0f5920922" TYPE="ext4" 

# -m number: 修改预留给管理员的空间百分比
[root@zabbix ~]# tune2fs -m 20 /dev/sdb1 
tune2fs 1.42.9 (28-Dec-2013)
Setting reserved blocks percentage to 20% (104857 blocks)

# -j: 将ext2升级为ext3
[root@zabbix ~]# mkfs.ext2 /dev/sdb1 
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
131072 inodes, 524288 blocks
26214 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=536870912
16 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912

Allocating group tables: done                            
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done 

[root@zabbix ~]# tune2fs -j /dev/sdb1
tune2fs 1.42.9 (28-Dec-2013)
Creating journal inode: done

[root@zabbix ~]# blkid /dev/sdb1 
/dev/sdb1: UUID="213524e4-0512-4705-98eb-3e564ce3a140" SEC_TYPE="ext2" TYPE="ext3" 

# -O: 文件系统属性启用或禁用; has_journal: 启用日志功能; ^has_journal: 关闭日志功能
[root@zabbix ~]# tune2fs -O ^has_journal /dev/sdb1
tune2fs 1.42.9 (28-Dec-2013)

[root@zabbix ~]# tune2fs -l /dev/sdb1 | grep -i 'journal'
Journal backup:           inode blocks

[root@zabbix ~]# tune2fs -O has_journal /dev/sdb1        
tune2fs 1.42.9 (28-Dec-2013)
Creating journal inode: done

[root@zabbix ~]# tune2fs -l /dev/sdb1 | grep -i 'journal'
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype sparse_super large_file
Journal inode:            8
Journal backup:           inode blocks

# -o: 调整文件系统的默认挂载选项; acl: 启用acl功能; ^acl: 关闭acl功能

# -U UUID: 修改UUID号

6.2.3 dumpe2fs

dumpe2fs用于查看ext文件系统超级快和文件系统布局信息.

# dumpe2fs [option] /dev/sdb1
[root@zabbix ~]# dumpe2fs /dev/sdb1
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem volume name:   <none>
Last mounted on:          <not available>
... # 信息太多, 省略掉
Group 15: (Blocks 491520-524287)
  Block bitmap at 491520 (+0), Inode bitmap at 491521 (+1)
  Inode table at 491522-492033 (+2)
  32254 free blocks, 8192 free inodes, 0 directories
  Free blocks: 492034-524287
  Free inodes: 122881-131072

# -h: 只查看超级快信息
[root@zabbix ~]# dumpe2fs -h /dev/sdb1
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem volume name:   <none>
...

6.3 文件系统检测

6.3.1 fsck命令

fsck用于检测文件系统.

# fsck.FS_TYPE /dev/DEVICE
[root@zabbix ~]# fsck.
fsck.btrfs   fsck.cramfs  fsck.ext2    fsck.ext3    fsck.ext4    fsck.minix   fsck.xfs     

[root@zabbix ~]# fsck.xfs /dev/sdb2 
If you wish to check the consistency of an XFS filesystem or
repair a damaged filesystem, see xfs_repair(8).

[root@zabbix ~]# xfs_repair /dev/sdb2 
Phase 1 - find and verify superblock...
Phase 2 - using internal log
        - zero log...
        - scan filesystem freespace and inode maps...
        - found root inode chunk
...
Phase 7 - verify and correct link counts...
done

# fsck -t FS_TYPE /dev/DEVICE
    # -a: 自动修复错误
    # -r: 交互式修复错误

6.3.2 e2fsck命令

e2fsck是ext系列文件系统专用的检查修复工具.

# e2fsck [option] /dev/DEVICE
    # -y: 自动修复
    # -f: 强制修复

七、挂载文件系统

可以通过/etc/mtab文件显示当前系统已挂载的所有设备

[root@zabbix ~]# cat /etc/mtab 
rootfs / rootfs rw 0 0
sysfs /sys sysfs rw,nosuid,nodev,noexec,relatime 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0

7.1 命令挂载方式

使用mount命令对文件系统进行挂载.

# mount [-fnrsvw] [-t vfstype] [-o options] /dev/DEVICE dir
[root@zabbix ~]# mount  /dev/sdb2 /mnt/xfs/             
[root@zabbix ~]# df -h
Filesystem                               Size  Used Avail Use% Mounted on
/dev/mapper/centos_docker--package-root   18G  2.5G   15G  15% /
devtmpfs                                 903M     0  903M   0% /dev
tmpfs                                    913M     0  913M   0% /dev/shm
tmpfs                                    913M  8.7M  904M   1% /run
tmpfs                                    913M     0  913M   0% /sys/fs/cgroup
/dev/sda1                                497M  124M  373M  25% /boot
tmpfs                                    183M     0  183M   0% /run/user/0
/dev/sdb2                               1014M   33M  982M   4% /mnt/xfs

# DEVICE: 指明要挂载的设备
    # /dev/sd[a-z][N]: 设备文件
    # -L 'LABEL': 卷标
    # -U 'UUID': UUID
    # 伪文件系统名称: proc, sysfs, devtmpfs, configfs

# dir: 挂载点; 必须事先存在(建议使用空目录), 并且如果进程正在使用中的挂载点无法umount

# 常用选项
    # -t vfstype: 指定要挂载的设备上的文件系统类型
    # -r: readonly, 只读挂载
    # -w: read and write, 读写挂载
    # -n: 不更新/etc/mtab
    # -a: 自动挂载所有支持自动挂载的设备(定义在/etc/fstab文件中, 且挂载选项中有“自动挂载”功能)
    # -B, --bind: 丙丁目录到另一个目录上

# -o options: 挂载文件系统的选项, 可多个同时使用, 使用逗号分隔, 默认挂载选项为defaults
    # async: 异步模式
    # sync: 同步模式
    # atime/noatime: 包含目录和文件的访问时间戳
    # diratime/nodiratime: 目录访问时间戳
    # auto/noauto: 是否支持自动挂载
    # exec/noexec: 是否支持将文件系统上应用程序运行为进程
    # dev/nodev: 是否支持此文件系统使用设备文件
    # suid/nosuid: 是否支持使用SUID权限
    # remount: 重新挂载
    # ro: 只读挂载
    # rw: 读写挂载
    # user/nouser: 是否运行普通用户挂载次设备
    # acl: 启用此文件系统上的acl功能

Note: 挂载点下原有文件在挂载完成后会被临时隐藏, 查看内核追踪到的已挂载的所有设备使用cat /proc/mounts.

7.2 卸载文件系统

使用umount命令.

# umount /dev/DEVICE|MOUNT_POINT

# fuser -v MOUNT_POINT: 查看正在访问指定文件系统的进程

# fuser -km MOUNT_POINT: 终止素有正在访问指定的文件系统的进程

7.3 启用交换分区

启用交换分区使用swapon命令, 禁用使用swapoff命令.

# swapon [option]... [DEVICE]
    # -a: 激活所有的交换分区
    # -p PRIORITY: 指定优先级
[root@zabbix ~]# free -m | grep -i "^swap"
Swap:          2047           0        2047
[root@zabbix ~]# swapon /dev/sdb1 
[root@zabbix ~]# free -m | grep -i "^swap"
Swap:          4095           0        4095

# 禁用交换分区
[root@zabbix ~]# swapoff /dev/sdb1 
[root@zabbix ~]# free -m | grep -i "^swap"
Swap:          2047           0        2047

7.4 文件系统空间占用等信息查看工具

df命令.

# df [OPTION]...
    # -h: human-readable
    # -i: inodes instead of blocks
    # -P: 以posix兼容的格式输入

7.6 查看某目录总体空间占用状态

du命令.

# du [OPTION]... DIR|FILE

7.7 内存空间使用状态

free命令.

#free [OPTION]
    # -m: 以MB为单位
    # -g: 以GB为单位

八、文件挂载的配置文件: /etc/fstab

/etc/fstab每行定义一个要挂载的文件系统:

[root@zabbix ~]# cat /etc/fstab 

#
# /etc/fstab
# Created by anaconda on Wed Jul  5 16:40:52 2017
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos_docker--package-root /                       xfs     defaults        0 0
UUID=ed124d13-489a-40dd-b64b-a64a26bff6c5 /boot                   xfs     defaults        0 0
/dev/mapper/centos_docker--package-swap swap                    swap    defaults        0 0

每一列对应的项目如下:

要挂载的设备或伪文件系统(设备文件|LABEL(LABEL= )|UUID(UUID= )|伪文件系统(proc、sysfs))    挂载点    文件系统类型    挂载选项(defaults,...)    转储频率(0: 不做转储; 1: 每天转储一次; 2: 每隔一天转储)    自检次序(0: 不自检; 1: 首先自检, 一般只有rootfs采用)