linux的文件系统为ext2,这个文件系统的组织离不开三个概念:inode,datablock和superblock。linux将文件的内容存放在datablock中,而将属性(包括文件的读写权限,所有者等)存放在inode中,而superblock中又记录了整个文件系统中的inode和datablock信息。l
inux文件系统在格式化的时候,这个系统中的inode数量和datablock的数量就已经决定了,除非重新格式化文件系统。每一个文件对应着一个inode,所以inode的数量就是系统中文件数量的最大值。但是一个文件可以占用多个datablock。
1.inode和datablock
inode中记录了一个文件的属性(包括文件的读写权限,所有者等)以及这个文件存放的datablock的号码。大体上的结构如下:
如上图,4号inode指向的datablock为2,7,13,15,这种文件的组织方式类似于索引结构。鸟哥的书中说,每个inode的大小为128个字节,但是我查了一下自己的系统发现inode的大小为256个字节,不过原理应该都是一样的,所以就按照128个字节来说吧。每一个datablock号在inode中占用4个字节,所以如果一个文件很大的话,那么必然要占用很多个datablock块,而inode中必然要记录很多的datablock号码,而inode中只有128个字节显然是不够用的,所以,下面来看一下linux是如何解决这个问题的。
在inode中一共有12个直接记录datablock地址,1个间接记录datablock地址,1个双间接记录datablock地址,一个3间接记录datablock地址。这个结构如下:
一个间接的地址是使用一个datablock来记录这个文件所在的datablock的地址,同样的,双间接和三间接也是这样的。这样假设datablock的大小为1K,一个文件系统中的最大文件可以为:12*1K+1*256*1K+1*256*256*1K+1*256*256*256*1K=16G,这样文件就可以足够大了。datablock的大小一般为1,2,4K。
2.superblock
superblock是用来记录整个文件系统中的inode和datablock的总量以及使用量和剩余量。我们可以使用下面的命令查看superblock的信息:
df
返回结果如下:
Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda1 25670972 21130640 3229664 87% / //注释:文件系统挂载点 udev 2003100 4 2003096 1% /dev tmpfs 805068 896 804172 1% /run none 5120 0 5120 0% /run/lock none 2012668 340 2012328 1% /run/shm
第一项为当前文件系统的挂载点,下面使用命令查看superblock的信息:
sudo dumpe2fs /dev/sda1 | more
返回结构如下:
dumpe2fs 1.42 (29-Nov-2011) Filesystem volume name: <none> Last mounted on: / Filesystem UUID: 043dec00-67ac-4cfb-a93f-6b180c20356d Filesystem magic number: 0xEF53 Filesystem revision #: 1 (dynamic) Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent 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: 1638400 //注释:inode的数量 Block count: 6553344 //注释:datablock的数量 Reserved block count: 327667 Free blocks: 1113264 //可用的datablock数量 Free inodes: 1311391 //可用的inode的数量 First block: 0 //第一个datablock的块 Block size: 4096 //datablock的大小 Fragment size: 4096 Reserved GDT blocks: 1022 Blocks per group: 32768 Fragments per group: 32768 Inodes per group: 8192 Inode blocks per group: 512 Flex block group size: 16 Filesystem created: Fri Dec 13 10:40:01 2013 Last mount time: Tue Apr 1 08:30:17 2014 Last write time: Fri Dec 13 10:50:12 2013 Mount count: 141 Maximum mount count: -1 Last checked: Fri Dec 13 10:40:01 2013 Check interval: 0 (<none>) Lifetime writes: 104 GB Reserved blocks uid: 0 (user root) Reserved blocks gid: 0 (group root) First inode: 11 Inode size: 256 //inode的大小 Required extra isize: 28
从上面返回的结果中还可以看到(上面没有列出来),linux的文件系统其实是将文件系统分成许多区块,如下:
Group 0: (Blocks 0-32767) [ITABLE_ZEROED] //第一个区块包含的datablock的起始与结束位置0-32767 Checksum 0x065a, unused inodes 0 Primary superblock at 0, Group descriptors at 1-2 //superblock位于第0个datablock块 Reserved GDT blocks at 3-1024 Block bitmap at 1025 (+1025), Inode bitmap at 1041 (+1041) //datablock位图和inode位图的位置 Inode table at 1057-1568 (+1057) 17195 free blocks, 0 free inodes, 551 directories //datablock剩余17195,而inode已经用完了 Free blocks: 10832-10847, 10864-10879, 10904-10943, 10952-10959, 10976-11063, 11072-11079, 11081-11083, 11088-11135, 11152-11194, 11196-11231, 11248 -11263, 11296-11311, 11318-11518, 11520-11615, 11663-11839, 11864-11880, 11882-11899, 11901-11905, 11907-11967, 11984-11992, 12026-12031, 12048-12110, 12112-12127, 12146-12175, 12184-12187, 12209-12215, 12224-12297, 12323-12387, 12412-12479, 12488-12510, 12544-12707, 12712-12735, 12760-12786, 12870- 13375, 13396-13407, 13423-13451, 13472-13503, 13532-13564, 13568-13587, 16103-16383, 17369-17407, 18018-32767 Free inodes: Group 1: (Blocks 32768-65535) [ITABLE_ZEROED] Checksum 0x9998, unused inodes 0 Backup superblock at 32768, Group descriptors at 32769-32770 Reserved GDT blocks at 32771-33792 Block bitmap at 1026 (bg #0 + 1026), Inode bitmap at 1042 (bg #0 + 1042) Inode table at 1569-2080 (bg #0 + 1569) 10545 free blocks, 0 free inodes, 997 directories Free blocks: 33848-33855, 34304-34319, 34360-34363, 34397-34399, 34403-34425, 34446-34447, 34455, 34461-34465, 34509-34510, 34560-34565, 34569-34615 , 34652-34655, 34670-34671, 34684-34687, 34735-34737, 34775, 34796-34799, 34809-34815, 34861-34865, 34904-34912, 35007-35071, 35135, 35180-35181, 3524 5-35327, 35576, 35608, 35616, 35645, 35671, 35675-35676, 35678-35679, 35688, 35690, 35692, 35694, 35697, 35701, 35713-35714, 35717-35719, 35751-35753, 35755, 35764-35775, 35777, 35794-35838, 35840-35903, 35905, 35922-35944, 35946-36204, 36224-36296, 36350-36380, 36382-36447, 36470-36488, 36490-36498 , 36500-36554, 36556-36599, 36608-36654, 36662-36682, 36684-36703, 36713-36716, 36718-36770, 36772-36863, 38918-38931, 38941-38951, 38960-38966, 38968 -39078, 39080-39087, 39096-39122, 39124-39315, 39317-39321, 39323-39401, 39403-39478, 39480-39515, 39517-39547, 39549-39653, 39655-39740, 39742-39747, 39749-39775, 39794-39817, 39819-39851, 39853-39856, 39858-39881, 39883-39904, 39906-39942, 39944-39963, 39965-39998, 40000-40001, 40003-40027, 40029- 40099, 40101-40114, 40116-40128, 40130-40159, 40168-40169, 40174-40177, 40179-40199, 40202-40203, 40217-40258, 40260-40276, 40278-40291, 40296-40342, 40344-40348, 40350-40365, 40367-40370, 40372-40411, 40413-40429, 40431-40457, 40459-40472, 40474-40503, 40505-40518, 40520-40527, 40538-40539, 40560-4 0573, 40575, 40592-40605, 40607-40641, 40643-40651, 40662-40663, 40688-40696, 40698-40815, 40823-40828, 40832-40879, 40881, 40890-40897, 40904-40969, 40978-41011, 41014-41071, 41074-41113, 41116-41119, 41122-41159, 41162-41183, 41186-41203, 41206-41213, 41216-41263, 41266-41303, 41306-41471, 41846-4 1888, 41890-41904, 41906-41912, 41914-41947, 41950-42495, 42498-42501, 42551-42593, 42616-42617, 42745-42746, 42755-42759, 42770-42776, 42788, 42805, 48790-48991, 48996-49031, 49036-49037, 49040-49151, 50382-50383, 50385-50386, 50390, 50394, 50399-50400, 50422, 50446, 52224-57355, 58800-58879, 59536 -59903, 60121, 60124-60125, 60128, 60416-60583, 61294-61439
通过将文件系统分成块,可以相对容易的管理linux的文件系统。
inode位图的作用就是用来记录那一个inode被使用了,哪一个inode没有被使用。同理datablock位图也是这个作用,它是用来记录datablock的使用情况。
3.在linux文件系统中寻找一个文件
我们都直到linux中将所有的一切都看作是一个文件。所以,linux中的目录也是一个文件,这个文件中记录了这个目录下的文件名及这个文件名所对应的inode号码。还有一个重要的知识点是,linux中根目录的inode的节点号为2,可以输入下面的指令来查看:
ls -ldi /
结果如下:
2 drwxr-xr-x 25 root root 4096 Mar 19 09:06 /
了解了这些后,下面就举一个例子来演示一下linux文件系统是如何寻找/etc/passwd文件的。
首先,linux找到inode号为2的inode,然后检查inode中的权限,发现权限为可读可执行,然后就读取2号inode节点指向的datablock块,
从中找到etc目录及其对应的inode号,假设这个inode号为INODE1,检查inode的权限,发现可读可执行,然后从INODE1号的inode找到其指向的datablock块,
从中读取passwd及其对应的inode号,假设这个inode号为INODE2,将这个inode的权限与当前用户的权限进行比较,决定是否允许存储,至此,我们找到了/etc/passwd文件。