磁盘分区表

磁盘分区表主要有两种格式,一种是限制较多的 MBR 分区表,一种是较新且限制较少的 GPT 分区表。

  1. MBR 分区表中,第一个扇区最重要,里面有:(1)主要开机区(Master boot record, MBR)及分区表(partition table), 其中 MBR 占有 446 bytes,而 partition table 则占有 64 bytes。
  2. GPT 分区表除了分区数量扩充较多之外,支持的磁盘容量也可以超过 2TB。

MBR与GPT的区别:

内存支持:MBR最多支持2T,GPT理论上无限制。

分区:MBR最多支持四个主分区,GPT无限制

文件系统通常会将这两部份的数据分别存放在不同的区块,权限与属性放置到inode 中,至于实际数据则放置到 data block 区块中,另外,还有一个超级区块 (superblock) 会记录整个文件系统的整体信息,包括 inode 与 block 的总量、使用量、剩余量等。

superblock,inode,block:

  1. superblock:记录此 filesystem 的整体信息,包括 inode/block 的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;
  2. inode:记录文件的属性,一个文件占用一个 inode,同时记录此文件的数据所在的 block 号码;
  3. block:实际记录文件的内容,若文件太大时,会占用多个 block 。

Ext2 文件系统的 block 限制:

  1. 原则上,block 的大小与数量在格式化完就不能够再改变了(除非重新格式化);
  2. 每个 block 内最多只能够放置一个文件的数据;
  3. 承上,如果文件大于 block 的大小,则一个文件会占用多个 block 数量;
  4. 承上,若文件小于 block ,则该 block 的剩余容量就不能够再被使用了(磁盘空间会浪费)。
inode记录的文件数据
  1. 该文件的存取模式(read/write/excute);
  2. 该文件的拥有者与群组(owner/group);
  3. 该文件的容量;
  4. 该文件建立或状态改变的时间(ctime);
  5. 最近一次的读取时间(atime);
  6. 最近修改的时间(mtime);
  7. 定义文件特性的旗标(flag),如 SetUID…;
  8. 该文件真正内容的指向 (pointer);

inode 的数量与大小也是在格式化时就已经固定了。

inode 特色
  1. 每个 inode 大小均固定为 128 bytes (新的 ext4 与 xfs 可设定到 256 bytes);
  2. 每个文件都仅会占用一个 inode 而已;
  3. 承上,因此文件系统能够建立的文件数量与 inode 的数量有关;
  4. 系统读取文件时需要先找到 inode,并分析 inode 所记录的权限与用户是否符合,若符合才能够开始实际读取 block 的内容。

以为每个文件只有一个inode,且inode的大小只有128bytes,当文件很大时inode采取了12 个直接,一个间接,一个双间接与一个三间接记录区。

inode 本身 (128 bytes),里面有 12 个直接指向 block 号码的对照,这 12 笔记录就能够直接取得 block 号码所谓的间接就是再拿一个 block 来当作记录 block 号码的记录区,如果文件太大时, 就会使用间接的 block 来记录编号。当中间接只是拿一个 block来记录额外的号码而已。 同理,如果文件持续长大,那么就会利用所谓的双间接,第一个 block 仅再指出下一个记录编号的 block 在哪里, 实际记录的在第二个 block 当中。依此类推,三间接就是利用第三层 block 来记录编号。

以1kblock为例,计算最大文件

  1. 12 个直接指向: 12*1K=12K
  2. 间接: 256*1K=256K 每笔 block 号码的记录会花去 4bytes,因此 1K 的大小能够记录 256 笔记录,因此一个间接可以记录的
  3. 双间接: 2562561K=256 2 K第一层 block 会指定 256 个第二层,每个第二层可以指定 256 个号码;
  4. 三间接: 256256256*1K=256 3 K第一层 block 会指定 256 个第二层,每个第二层可以指定 256 个第三层,每个第三层可以指定 256 个号码,因此总额大小如上;

总额:将直接、间接、双间接、三间接加总,得到 12 + 256 + 256256 + 256256*256 (K) = 16GB。

这个方法不能用在 2K 及 4K block 大小的计算中, 因
为大于 2K 的 block 将会受到 Ext2 文件系统本身的限制,所以计算的结果会不太符合

Ext4 文件系统的 inode 容量已经可以扩大到 256bytes 了,更大的 inode 容量,可以纪录更多的文件系统信息,包括新的 ACL 以及 SELinux 类型等, 当然,可以纪录的单一文件容量达 16TB 且单一文件系统总容量可达1EB。

Superblock (超级区块)

Superblock 是记录整个 filesystem 相关信息的地方, 没有 Superblock ,就没有这个 filesystem 了。他记录的信息主要有:

  1. block 与 inode 的总量;
  2. 未使用与已使用的 inode / block 数量;
  3. block 与 inode 的大小 (block 为 1, 2, 4K,inode 为 128bytes 256bytes);
  4. filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘(fsck) 的时间等文件系统的相关信息;
  5. 一个 valid bit 数值,若此文件系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1 。

superblock 的大小为 1024bytes,每个 block group 都可能含有superblock,一个文件系统应该仅有一个superblock 而已事实上除了第一个 block group 内会含有 superblock 之外,后续的 block group 不一定含有 superblock , 而若含有 superblock 则该 superblock 主要是做为第一个 block group 内 superblock 的备份,这样可以进行 superblock 的救援

1
ls -i 显示文件的所占用的inode号码

EXT2/EXT3/EXT4 文件的存取与日志式文件系统的功能

  1. 先确定用户对于欲新增文件的目录是否具有 w 与 x 的权限,若有的话才能新增;
  2. 根据 inode bitmap 找到没有使用的 inode 号码,并将新文件的权限/属性写入;
  3. 根据 block bitmap 找到没有使用中的 block 号码,并将实际的数据写入 block 中,且更新 inode 的 block指向数据;
  4. 将刚刚写入的 inode 与 block 数据同步更新 inode bitmap 与 block bitmap,并更新 superblock 的内容。
日志式文件系统 (Journaling filesystem)

为了避免文件系统不一致的情况发生,filesystem 当中规划出一个区块,该区块专门在记录写入或修订文件时的步骤。

  1. 预备:当系统要写入一个文件时,会先在日志记录区块中纪录某个文件准备要写入的信息;
  2. 实际写入:开始写入文件的权限与数据;开始更新 metadata 的数据;
  3. 结束:完成数据与 metadata 的更新后,在日志记录区块当中完成该文件的纪录。

linux支持的文件系统

  1. 传统文件系统:ext2 / minix / MS-DOS / FAT (用 vfat 模块) / iso9660 (光盘)等等;
  2. 日志式文件系统: ext3 /ext4 / ReiserFS / Windows’ NTFS / IBM’s JFS / SGI’s XFS / ZFS
  3. 网络文件系统: NFS / SMBFS
1
2
ls -l /lib/modules/$(uname -r)/kernel/fs
查看系统所支持的文件系统

系统目前已加载到内存中支持的文件系统则有:

1
cat /proc/filesystems

文件系统的命令操作

df:列出文件系统的整体磁盘使用量

du:评估文件系统的磁盘使用量(常用在推估目录所占容量)

1
2
3
4
5
6
7
8
9
df [-ahikHTm] [目录或文件名]
选项与参数:
-a :列出所有的文件系统,包括系统特有的 /proc 等文件系统;
-k :以 KBytes 的容量显示各文件系统;
-m :以 MBytes 的容量显示各文件系统;
-h :以人们较易阅读的 GBytes, MBytes, KBytes 等格式自行显示;
-H :以 M=1000K 取代 M=1024K 的进位方式;
-T :连同该 partition 的 filesystem 名称 (例如 xfs) 也列出;
-i :不用磁盘容量,而以 inode 的数量来显示
1
2
3
4
5
6
7
8
du [-ahskm] 文件或目录名称
选项与参数:
-a :列出所有的文件与目录容量,因为默认仅统计目录底下的文件量而已。
-h :以人们较易读的容量格式 (G/M) 显示;
-s :列出总量而已,而不列出每个各别的目录占用容量;
-S :不包括子目录下的总计,与 -s 有点差别。
-k :以 KBytes 列出容量显示;
-m :以 MBytes 列出容量显示;

链接:

符号链接只想文件名,源文件名被删无法使用,实体链接只想inode,与其他文件无关

磁盘分区,格式化,校验及挂载

lsblk 列出系统上的所有磁盘列表
1
2
3
4
5
6
7
8
9
10
lsblk [-dfimpt] [device]
选项与参数:
-d :仅列出磁盘本身,并不会列出该磁盘的分区数据
-f :同时列出该磁盘内的文件系统名称
-i :使用 ASCII 的线段输出,不要使用复杂的编码 (再某些环境下很有用)
-m :同时输出该装置在 /dev 底下的权限数据 (rwx 的数据)
-p :列出该装置的完整文件名!而不是仅列出最后的名字而已。
-t :列出该磁盘装置的详细数据,包括磁盘队列机制、预读写的数据量大小等
列出本系统下的所有磁盘与磁盘内的分区信息
[root@study ~]# lsblk
blkid 列出装置的 UUID 等参数
1
每一行代表一个文件系统,主要列出装置名称、 UUID 名称以及文件系统的类型 (TYPE)
parted 列出磁盘的分区表类型与分区信息
1
2
列出 /dev/vda 磁盘的相关数据
[root@study ~]# parted /dev/vda print
磁盘分区: gdisk/fdisk

MBR 分区表请使用 fdisk 分区, GPT 分区表请使用 gdisk 分区

lsblk 或 blkid 先找到磁盘,再用 parted /dev/xxx print 来找出内部的分区表类型,之后才用 gdisk 或 fdisk 来操作系统。 上表中可以发现 gdisk 会扫描 MBR 与 GPT 分区表,不过这个软件还是单纯使用在 GPT 分区表比较好

partprobe 更新 Linux 核心的分区表信息
mkfs磁盘格式化

XFS 文件系统 mkfs.xfs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[root@study ~]# mkfs.xfs [-b bsize] [-d parms] [-i parms] [-l parms] [-L label] [-f] \
[-r parms] 装置名称
选项与参数:
关于单位:底下只要谈到『数值』时,没有加单位则为 bytes 值,可以用 k,m,g,t,p (小写)等来解释
比较特殊的是 s 这个单位,它指的是 sector 的『个数』喔!
-b :后面接的是 block 容量,可由 512 到 64k,不过最大容量限制为 Linux 的 4k 喔!
-d :后面接的是重要的 data section 的相关参数值,主要的值有:
agcount=数值 :设定需要几个储存群组的意思(AG),通常与 CPU 有关
agsize=数值 :每个 AG 设定为多少容量的意思,通常 agcount/agsize 只选一个设定即可
file :指的是『格式化的装置是个文件而不是个装置』的意思!(例如虚拟磁盘)
size=数值 :data section 的容量,亦即你可以不将全部的装置容量用完的意思
su=数值 :当有 RAID 时,那个 stripe 数值的意思,与底下的 sw 搭配使用
sw=数值 :当有 RAID 时,用于储存数据的磁盘数量(须扣除备份碟与备用碟)
sunit=数值 :与 su 相当,不过单位使用的是『几个 sector(512bytes 大小)』的意思
swidth=数值 :就是 su*sw 的数值,但是以『几个 sector(512bytes 大小)』来设定
-f :如果装置内已经有文件系统,则需要使用这个 -f 来强制格式化才行!
-i :与 inode 有较相关的设定,主要的设定值有:
:最小是 256bytes 最大是 2k,一般保留 256 就足够使用了!
size=数值
internal=[0|1]:log 装置是否为内建?预设为 1 内建,如果要用外部装置,使用底下设定
logdev=device :log 装置为后面接的那个装置上头的意思,需设定 internal=0 才可!
:指定这块登录区的容量,通常最小得要有 512 个 block,大约 2M 以上才行!
size=数值
-L :后面接这个文件系统的标头名称 Label name 的意思!
-r :指定 realtime section 的相关设定值,常见的有:
extsize=数值
:就是那个重要的 extent 数值,一般不须设定,但有 RAID 时,
最好设定与 swidth 的数值相同较佳!最小为 4K 最大为 1G 。


将分区 /dev/vda4 格式化为 xfs 文件系统
[root@study ~]# mkfs.xfs /dev/vda4
1
2
找出你系统的 CPU 数,并据以设定你的 agcount 数值
[root@study ~]# grep 'processor' /proc/cpuinfo

EXT4 文件系统 mkfs.ext4

1
2
3
4
5
6
[root@study ~]# mkfs.ext4 [-b size] [-L label] 装置名称
选项与参数:
-b :设定 block 的大小,有 1K, 2K, 4K 的容量,
-L :后面接这个装置的标头名称。
将 /dev/vda5 格式化为 ext4 文件系统
[root@study ~]# mkfs.ext4 /dev/vda5

其他文件系统 mkfs

1
2
3
4
root@study ~]# mkfs[tab][tab]	//按两下tab键
mkfs mkfs.btrfs mkfs.cramfs mkfs.ext2 mkfs.ext3
mkfs.fat mkfs.minix mkfs.msdos mkfs.vfat mkfs.xfs
mkfs.ext4

文件系统检验

xfs_repair 处理 XFS 文件系统

当有 xfs 文件系统错乱才需要使用这个指令

1
2
3
4
5
xfs_repair [-fnd] 装置名称
选项与参数:
-f:后面的装置其实是个文件而不是实体装置
-n :单纯检查并不修改文件系统的任何数据 (检查而已)
-d :通常用在单人维护模式底下,针对根目录 (/) 进行检查与修复的动作!很危险!不要随便使用
fsck.ext4 处理 EXT4 文件系统
1
2
3
4
5
6
7
8
fsck.ext4 [-pf] [-b superblock] 装置名称
选项与参数:
-p :当文件系统在修复时,若有需要回复 y 的动作时,自动回复 y 来继续进行修复动作。
-f :强制检查!一般来说,如果 fsck 没有发现任何 unclean 的旗标,不会主动进入
细部检查的,如果您想要强制 fsck 进入细部检查,就得加上 -f 旗标啰!
-D :针对文件系统下的目录进行优化配置。
-b :后面接 superblock 的位置!一般来说这个选项用不到。但是如果你的 superblock 因故损毁时,
透过这个参数即可利用文件系统内备份的 superblock 来尝试救援。一般来说,superblock 备份在:1K block 放在 8193, 2K block 放在 16384, 4K block 放在 32768

文件系统挂载与卸除

  1. 单一文件系统不应该被重复挂载在不同的挂载点(目录)中;
  2. 单一目录不应该重复挂载多个文件系统;
  3. 要作为挂载点的目录,理论上应该都是空目录才是。

如果你要用来挂载的目录里面并不是空的,那么挂载了文件系统之后,原目录下的东西就会暂时的消失。 举个例子来说,假设你的 /home 原本与根目录 (/) 在同一个文件系统中,底下原本就有 /home/test 与 /home/vbird 两个目录。然后你想要加入新的磁盘,并且直接挂载 /home底下,那么当你挂载上新的分区槽时,则 /home 目录显示的是新分区槽内的资料,至于原先的 test 与vbird 这两个目录就会暂时的被隐藏掉了!注意喔!并不是被覆盖掉, 而是暂时的隐藏了起来,等到新分区槽被卸除之后,则 /home 原本的内容就会再次的跑出来啦!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[root@study ~]# mount -a
[root@study ~]# mount [-l]
[root@study ~]# mount [-t 文件系统] LABEL='' 挂载点
[root@study ~]# mount [-t 文件系统] UUID='' 挂载点
[root@study ~]# mount [-t 文件系统] 装置文件名
选项与参数:
-a :依照配置文件 /etc/fstab 的数据将所有未挂载的磁盘都挂载上来
-l :单纯的输入 mount 会显示目前挂载的信息。加上 -l 可增列 Label 名称!
-t :可以加上文件系统种类来指定欲挂载的类型。常见的 Linux 支持类型有:xfs, ext3, ext4,
reiserfs, vfat, iso9660(光盘格式), nfs, cifs, smbfs (后三种为网络文件系统类型)
-n:在默认的情况下,系统会将实际挂载的情况实时写入 /etc/mtab 中,以利其他程序的运作。
但在某些情况下(例如单人维护模式)为了避免问题会刻意不写入。此时就得要使用 -n 选项。
-o:后面可以接一些挂载时额外加上的参数!比方说账号、密码、读写权限等:
async, sync:
此文件系统是否使用同步写入 (sync) 或异步 (async) 的
内存机制,请参考文件系统运作方式。预设为 async。
atime,noatime: 是否修订文件的读取时间(atime)。为了效能,某些时刻可使用 noatime
ro, rw: 挂载文件系统成为只读(ro) 或可擦写(rw)
auto, noauto: 允许此 filesystem 被以 mount -a 自动挂载(auto)
dev, nodev: 是否允许此 filesystem 上,可建立装置文件? dev 为可允许
suid, nosuid: 是否允许此 filesystem 含有 suid/sgid 的文件格式?
exec, noexec: 是否允许此 filesystem 上拥有可执行 binary 文件?
user, nouser: 是否允许此 filesystem 让任何使用者执行 mount ?一般来说,mount 仅有 root 可以进行,但下达 user 参数,则可让一般 user 也能够对此 partition 进行 mount 。
defaults:默认值为:rw, suid, dev, exec, auto, nouser, and async

Linux 支持的文件系统之驱动程序都写在如下的目录中:

1
2
/lib/modules/$(uname -r)/kernel/fs/
ext4 的驱动程序就写在『/lib/modules/$(uname -r)/kernel/fs/ext4/』这个目录

umount (将装置文件卸除)

1
2
3
4
5
umount [-fn] 装置文件名或挂载点
选项与参数:
-f :强制卸除!可用在类似网络文件系统 (NFS) 无法读取到的情况下;
-l :立刻卸除文件系统,比 -f 还强!
-n :不更新 /etc/mtab 情况下卸除。

磁盘/文件系统参数修订

1
2
3
4
5
6
7
8
9
10
11
12
13
14
xfs_admin 修改 XFS 文件系统的 UUID 与 Label name
xfs_admin [-lu] [-L label] [-U uuid] 装置文件名
选项与参数:
-l :列出这个装置的 label name
-u :列出这个装置的 UUID
-L :设定这个装置的 Label name
-U :设定这个装置的 UUID 喔!
设定 /dev/vda4 的 label name 为 vbird_xfs,并测试挂载
[root@study ~]# xfs_admin -L vbird_xfs /dev/vda4
writing all SBs new label = "vbird_xfs"
# 产生新的 LABEL 名称啰!
[root@study ~]# xfs_admin -l /dev/vda4
label = "vbird_xfs"
[root@study ~]# mount LABEL=vbird_xfs /data/xfs/

tune2fs 修改 ext4 的 label name 与 UUID

1
2
3
4
5
6
7
8
9
10
11
tune2fs [-l] [-L Label] [-U uuid] 装置文件名
选项与参数:
-l :类似 dumpe2fs -h 的功能~将 superblock 内的数据读出来~
-L :修改 LABEL name
-U :修改 UUID 啰!
列出 /dev/vda5 的 label name 之后,将它改成 vbird_ext4
[root@study ~]# dumpe2fs -h /dev/vda5 | grep name
[root@study ~]#tune2fs -L vbird_ext4 /dev/vda5
[root@study ~]# dumpe2fs -h /dev/vda5 | grep name
Filesystem volume name:vbird_ext4
[root@study ~]# mount LABEL=vbird_ext4 /data/ext4

开机挂载 /etc/fstab 及 /etc/mtab

挂载的一些限制:

  1. 根目录 / 是必须挂载的,而且一定要先于其它 mount point 被挂载进来。
  2. 其它 mount point 必须为已建立的目录,可任意指定,但一定要遵守必须的系统目录架构原则 (FHS)
  3. 所有 mount point 在同一时间之内,只能挂载一次。
  4. 所有 partition 在同一时间之内,只能挂载一次。
  5. 如若进行卸除,您必须先将工作目录移到 mount point(及其子目录) 之外。