Linux教程

APUE Unix/Linux文件系统

本文主要是介绍APUE Unix/Linux文件系统,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1. 磁盘布局

1.1 分区

一个磁盘可分为多个分区, 每个分区须先用格式化工具(如mkfs)格式化成指定格式的文件系统, 才能用于存储文件. 

磁盘文件系统布局:

 

1.2 块

block,  文件系统中的最小存储单位, 大小在格式化时规定

设置方式, 格式化时输入命令:

$ mke2fs -b 1024 # 通常1024, 2048, 或 4096

 

1.3 自举块/启动块/Boot Block

用于存放磁盘分区信息和启动信息, 其大小是确定的, ext2文件系统启动块大小是1KB, 由PC标准规定. 任何文件系统都不能使用启动块. 启动块之后, 才是ext2文件系统.

1.4 柱面组/块组/Block Group

分区 = 自举块 + 超级块 + 柱面组0..n. 每个柱面组大小一样.

而柱面组 = 超级块 + 配置信息 + i节点图 + 块位图 + i节点数组(i节点0..m) + 数据块

 

柱面组组成:

1) 超级块/Super Block

描述整个分区的文件系统信息, 例如块大小, 文件系统版本号, 上次mount(挂载)时间等.

超级块在每个块组开头都有一份拷贝(图中称为超级块副本).

超级块丢失 => 整个块组的数据丢失

2) 配置信息

在ext2~4文件系统中, 这部分称为块组描述符表(GDT, Group Descriptor Table), 由很多块组描述符组成, 本分区有多少个块组就有多少个块组描述符.

每个块组描述符(Group Descriptor)存储一个块组的描述信息, 如该块组从哪儿开始是inode表(i节点数组), 从哪儿开始是数据块(Data Blocks), 空闲inode和数据块还有多少个等.

同超级块, 块组描述符在每个块组的开头也有一份拷贝.

块组描述符丢失 => 整个块组的数据丢失

3) i节点图/inode Bitmap

本身占一个块, 如4096byte (4KB),  其中每个bit表示一个inode(i节点)是否空闲.

4) 块位图/Block Bitmap

每个bit位代表本块组中的一个块是否空闲,

- 1 表示该块已用;

- 0 表示该块空闲;

一个块组(Block Group, 柱面组)中的块是这样利用的:

数据块存储所有文件的数据, 如某个分区的块大小1024byte, 某个文件2049byte, 就需要3个数据块存储: 前2个数据块都存放1024byte, 第3个数据块存放1byte;

5)i节点数组/inode Table

inode这里的i可用理解成information node, inode Table专门用于存放文件的描述信息(区别于文件数据), 如文件类型(常规, 目录, fifo文件, 符号链接等), 访问权限, 文件大小, 创建、最后一次修改/访问时间(可用ls -l命令查询).

每个文件都有一个inode, 一个块组(Block Group)中所有inode组成inode表.

inode表总共占多少个块在格式化的时候, 就要决定并写入块组描述符, 由GDT/配置信息管理. mke2fs(格式化工具)的默认策略是一个块组有多少个8KB, 就分配多少个inode.

mke2fs -i命令可以手动指定每多少个字节分配一个inode.

 

 

 

 

6) 数据块/Data Blocks

不同文件类型, 有不同的存储情况:

  • 常规文件

文件的数据存储在数据块中

  • 目录

目录下所有文件名和目录名存放在数据块中,  除文件名外, ls -l命令查看到的所有信息都保存在inode中.

注意: 文件名是存放在所在目录的数据块中, 而非inode中.

  • 符号链接

符号链接的文件内容就是目标路径名. 

如果目标路径名较短, 则直接保存在inode中, 以便快速查找; 如果目标路径名较长, 则分配一个数据块来保存.

---- 疑问: 何为路径名较短, 标准是什么? 如何查看和设置?

  • 设备文件/FIFO/socket等特殊文件

没有数据块, 设备文件的主设备号和此设备号, 保存在inode中.

 

创建testdir后的文件系统实例, 表明硬链接所代表的链接计数如何计算.

注意:

1. 叶子目录(没有子目录的目录)链接计数为2, 分别是"."和命名该目录的目录项(我的理解一般是"..");

2. 普通文件(非目录)链接计数为1, 因为只有当前目录(".", 普通文件的父目录)指向普通文件;

 

 

硬链接和符号链接的区别:

1)inode链接计数

硬链接是文件的别名, 每增加一个, 文件对应的i节点的链接计数+1. 链接计数表示, 目录块中指向i节点编号的目录项的个数;

符号链接是文件的间接指针, 其文件内容直接存储链接的文件的路径名, 不会影响链接计数;

2)所处位置

硬链接一般要求链接和文件位于同一个文件系统中;

符号链接没有这个限制;

3)创建权限

只有root用户才能创建硬链接;

符号链接没有这个限制;

 

具体验证方法, 可查看下面的实验.

2. FAQ

如何查看一个数据块的大小(Block Size)?

参见 Linux查看系统块大小

(1)stat查看 根目录"/" 所在磁盘分区的Block Size

$ stat -f /
  文件:"/"
    ID:7e5c5070d17ef5e7 文件名长度:255     类型:ext2/ext3
块大小:4096       基本块大小:4096
    块:总计:7220231    空闲:3479622    可用:3107091
Inodes: 总计:1843200    空闲:1533150

这里4096(byte)就是Block Size

 

(2)fdisk -l查看指定磁盘分区的Block Size (/dev/sda?,  根据实际需要查询的分区决定)

$ sudo fdisk -l /dev/sda6
Disk /dev/sda6:44 GiB,47227863040 字节,92241920 个扇区
单元:扇区 / 1 * 512 = 512 字节
扇区大小(逻辑/物理):512 字节 / 4096 字节
I/O 大小(最小/最佳):4096 字节 / 4096 字节

这里4096就是Block Size

 

(3) tune2fs命令查看指定分区的Block Size

$ sudo tune2fs -l /dev/sda6 | grep "Block size"
Block size:               4096

 

(4)blockdev命令查看指定分区的Block Size

$ sudo blockdev --getbsz /dev/sda6
4096

 

如何查看文件系统类型?

使用lsblk命令, 参见 如何查看linux文件系统类型?

$ lsblk -f

 

如何创建并查看符号链接?

使用ln -s命令创建, ls -l命令查看

如果已经有了hello文件, 则不用touch命令创建. 用ln命令创建了halo后, 发现hello的硬链接数1不变, 而halo文件大小为7byte, 即内容文件名./hello (7个字符).

$ touch hello
$ ln -s ./hello halo
$ ls -l
总用量 0
lrwxrwxrwx 1 martin martin 7 5月  15 00:59 halo -> ./hello
-rw-r--r-- 1 martin martin 0 5月  15 00:58 hello

 

如何创建并查看硬链接?

假设已经用touch命令创建了hello. 在用ln命令创建了hello2后, 发现hello的硬链接数由原来的1变成了2, 而且新建的硬链接文件hello2链接数也是2(与hello一样).

我们知道, 普通文件硬链接数一般是1, 也就是说, 如果一个普通文件硬链接数>1, 说明有其他硬链接文件指向了该文件.

$ ln ./hello hello2
$ ls -l
总用量 0
lrwxrwxrwx 1 martin martin 7 5月  15 00:59 halo -> ./hello
-rw-r--r-- 2 martin martin 0 5月  15 00:58 hello
-rw-r--r-- 2 martin martin 0 5月  15 00:58 hello2

 

如果往文件写入数据, 是否会影响符号链接文件/硬链接文件?

往文件hello写3个字符"abc", 可以看到, 符号链接文件hallo并未受到影响, 而硬链接文件helo2文件大小改变.

$ cat hello
abc
$ ls -l
总用量 8
lrwxrwxrwx 1 martin martin 7 5月  15 00:59 halo -> ./hello
-rw-r--r-- 2 martin martin 4 5月  15 01:05 hello
-rw-r--r-- 2 martin martin 4 5月  15 01:05 hello2

 

3. 参考

Ext4文件系统架构分析(一)

 

这篇关于APUE Unix/Linux文件系统的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!