一、linux文件系统如何存储数据(以ext4为例)?
我们知道,linux中一切皆文件,文件包括属性和内容两部分(当然,还包括文件名,不过文件名实质是其所属目录文件的内容,目录文件也有inode号)。linux文件系统将这两类数据分别存储于不同的区域,属性信息放置于inode区(即元数据区)中,实际内容放置于data block区中,另外,还有一个superblock(超级块)会记录整个文件系统的整体信息。
1、inode:index node,即索引节点,存放文件的属性信息(如文件类型、大小、权限、属主属组、时间戳等)和文件内容所在的block编号
1)inode是文件惟一标识,系统根据文件名先找到inode,并首先分析是否符合inode中记录的权限,符合后根据block编号找到数据块读取内容。
2)ext4格式的文件系统的每个inode大小为256bytes(之前为128bytes),这在磁盘(或分区)格式化(创建文件系统)时就确定了。inode记录一个block编号占用4byte,故一个inode中所能记录的block编号是有限的,为此,当一个inode不够记录时,可再借用若干个block帮助其记录block编号,并且可以使用多级间接block,如下图:
2、block(块):存放文件实际内容
1)每个block大小有1K,2K及4K三种,其大小也是在磁盘(或分区)格式化时就确定了,要改变需重新格式化
2)block大小的差异,会导致该文件系统所能支持的最大磁盘(或分区)容量和最大文件容量不同。block越大,文件系统所能支持的最大磁盘(或分区)容量和最大文件容量也越大
3)每个block内只能存放一个文件的内容
4)若文件内容大小大于单个block,则该文件会占用多个block;若占不满一个block,这个block中的剩余空间也将浪费,因此block大小的选取也很重要:
若经常存储小文件,而block较大无疑会浪费很多空间;但block较小的话,大型文件会占用较多的block数,这样inode中也会记录更多的block编号,由此会降低系统读写性能。所以block大小的选取应根据实际情况权衡
3、superblock:存放此文件系统的整体信息,包括inode/block大小、inode/block总量、使用量、剩余量、文件系统格式等。一个文件系统仅有一个superblock,位于组0中,这个块很重要,因此通常还有一个备份位于其它组中,其大小一般为1K。
查看超级块信息:dumpe2fs [-h] DEVICE,如dempe2fs -h /dev/sda2
tune2fs -l DEVICE
4、由于文件系统通常很大,所以将所有inode和block放在一起的话查找起来极为不便,为此ext4文件系统在创建时实际是分成多个组(group)的,组编号从0开始。每个组都有独立的inode/block/superblock系统,这样管理起来就简易多了。
[root@localhost ~]# dumpe2fs /dev/sda2 ... Last mounted on: / Filesystem UUID: b37fe9d5-cef1-4e11-a9a7-b82df4f692f0 ... Inode count: 655360 # inode总数 Block count: 2621440 # block总数 Reserved block count: 131072 # 保留的block数 Free blocks: 1827155 # 可用的block数 Free inodes: 571880 # 可用的inode数 First block: 0 Block size: 4096 # 每个block大小,4K Fragment size: 4096 Reserved GDT blocks: 639 Blocks per group: 32768 # 每个组的block数 Fragments per group: 32768 Inodes per group: 8192 # 每个组的inode数 Inode blocks per group: 512 Flex block group size: 16 ... Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 256 # 每个inode的大小 ... Group 0: (Blocks 0-32767) [ITABLE_ZEROED] Checksum 0x556c, unused inodes 0 Primary superblock at 0, Group descriptors at 1-1 # 此组的第0号块为superblock Reserved GDT blocks at 2-640 Block bitmap at 641 (+641), Inode bitmap at 657 (+657) Inode table at 673-1184 (+673) 21647 free blocks, 0 free inodes, 995 directories Free blocks: 11121-32767 Free inodes: Group 1: (Blocks 32768-65535) [ITABLE_ZEROED] Checksum 0xeac9, unused inodes 0 Backup superblock at 32768, Group descriptors at 32769-32769 # superblock备份位于此组中 ...
5、当我们要创建一个文件时,当然要寻找一个空的inode和若干个空的block,那么哪些inode和block块是空的呢?这时候就需要求助于inodemap(inode位图)和bitmap(块位图)了,bitmap用于描述磁盘(或分区)上每个数据块的使用情况。inodemap和bitmap均处于元数据区
6、设备文件是一类特殊的文件,只有inode而无内容,它们关联至一个驱动程序,进而跟对应的硬件设备打交道
二、文件链接
1、我们知道,文件名即是通向文件inode的路径,所谓“条条大路通罗马”,指向一个inode的路径当然也可以不止一条。而且,指向一个inode的方式有两种:
1)A→inode1,B→inode1
文件名A和B都直接指向同一个inode,这种情况,我们就称A或B为对方的硬链接。自然删除其中一个文件名并不影响另一个文件名的访问。
①硬链接是有限制的:不能跨分区;不能对目录建立硬链接
②一个inode可以被引用多次,其有计数器,增加一条路径则加1,删除一条路径则减1,直至降为0,此inode和它指向的磁盘块才被标记为空闲
注意:建立硬链接是不同于复制的,硬链接只是增加文件路径而已,而复制是建立一个全新的文件,会在磁盘中占用inode和block块
2)A→inode1,B→inode2→A→inode1
B并不直接指向inode1,而是先要通过A。B指向另一个inode2,随后读取到内容为文件名A,由此再指向inode1。这时候,我们称B为A的软链接(符号链接)。自然,删除A后B就无法访问最终目标文件内容。
①可以对目录创建软链接,且不受分区限制
②创建软链接并不增加inode计数,因为软链接并不直接指向目标inode
2、文件移动:
在同一个分区移动文件仅是改变文件访问路径,并不改变inode号
跨分区移动,在新分区创建文件,把数据复制过去,删除原分区数据
3、使用ln命令建立链接
用法:ln [option]... SOURCE LINK
不加任何选项则为建立硬链接
常用选项:
-f:建立链接时先将与LINK同档名的文件删除
-i:在删除与LINK同档名的文件之前先进行询问
-s:建立软链接
-d:在建立链接时先将与LINK同档名的文件进行备份
注意:建立软链接时指定源文件名要使用绝对路径(若链接文件名与源文件名在同一目录下,还可使用相对路径,否则必须使用绝对路径),因为链接文件直接读取的块内容是源文件名,若源文件名使用相对路径,它将无法再通过这个不完整的路径通达最终文件的inode,如下:
4、链接文件的默认权限为777,但用户是否能读取文件内容要以源文件的权限为准
[tesla@localhost ~]$ ln shakespear /tmp/literature # 建立硬链接 [tesla@localhost ~]$ ll -i shakespear /tmp/literature # 可以看到,链接文件与源文件指向同一个inode(第一列),且inode连结数已变为2 145388 -rw-rw-r-- 2 tesla tesla 39 Oct 10 01:31 shakespear 145388 -rw-rw-r-- 2 tesla tesla 39 Oct 10 01:31 /tmp/literature [tesla@localhost ~]$ rm -f shakespear [tesla@localhost ~]$ ll /tmp/literature -rw-rw-r-- 1 tesla tesla 39 Oct 10 01:31 /tmp/literature [tesla@localhost ~]$ cat /tmp/literature # 删除源文件名后仍能访问文件内容 To be or not to be,that is a question. [tesla@localhost ~]$ ln -s heracleitus /tmp/truth # 因源文件名使用了相对路径,软链接建立失败,见后面 [tesla@localhost ~]$ ll -i heracleitus /tmp/truth 145394 -rw-rw-r-- 1 tesla tesla 42 Oct 10 03:05 heracleitus 393219 lrwxrwxrwx 1 tesla tesla 11 Oct 10 03:11 /tmp/truth -> heracleitus [tesla@localhost ~]$ cat /tmp/truth # 无法访问 cat: /tmp/truth: No such file or directory [tesla@localhost ~]$ ln -s /home/tesla/heracleitus /tmp/truth2 # 重新建立软链接 [tesla@localhost ~]$ ll -i /home/tesla/heracleitus /tmp/truth2 # 可以看到源文件名和链接文件名指向不同inode 145394 -rw-rw-r-- 1 tesla tesla 42 Oct 10 03:05 /home/tesla/heracleitus 397175 lrwxrwxrwx 1 tesla tesla 23 Oct 10 03:16 /tmp/truth2 -> /home/tesla/heracleitus [tesla@localhost ~]$ cat /tmp/truth2 # 可以访问最终文件内容了 There is nothing permanent except change. [tesla@localhost ~]$ rm -f /home/tesla/heracleitus [tesla@localhost ~]$ cat /temp/truth2 # 删除源文件名后无法访问最终文件内容了 cat: /temp/truth2: No such file or directory [tesla@localhost ~]$ ln -s /etc /home/tesla/test # 也可对目录创建软链接 [tesla@localhost ~]$ ls test abrt cron.deny ...