inode on ext2 ext3 file system
本文包含以下内容:
1. 什么是inode
理解inode,要从文件储存说起。文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)。操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。通过下面的命令可以查看块的大小。
1 [root@pss1sitwls1a ~]# df -h . 2 Filesystem Size Used Avail Use% Mounted on 3 /dev/cciss/c0d0p3 127G 113G 7.8G 94% / 4 [root@pss1sitwls1a ~]# tune2fs -l /dev/cciss/c0d0p3 5 tune2fs 1.35 (28-Feb-2004) 6 Filesystem volume name: / 7 Last mounted on: <not available> 8 Filesystem UUID: aa69a26b-623a-419c-9734-26e6137e93e4 9 Filesystem magic number: 0xEF53 10 Filesystem revision #: 1 (dynamic) 11 Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery sparse_super large_file 12 Default mount options: (none) 13 Filesystem state: clean 14 Errors behavior: Continue 15 Filesystem OS type: Linux 16 Inode count: 16859136 17 Block count: 33704370 18 Reserved block count: 1685218 19 Free blocks: 3644491 20 Free inodes: 15663501 21 First block: 0 22 Block size: 4096 23 Fragment size: 4096 24 Reserved GDT blocks: 1015 25 Blocks per group: 32768 26 Fragments per group: 32768 27 Inodes per group: 16384 28 Inode blocks per group: 512 29 Filesystem created: Mon Nov 3 13:44:20 2008 30 Last mount time: Mon Oct 29 09:24:24 2012 31 Last write time: Mon Oct 29 09:24:24 2012 32 Mount count: 24 33 Maximum mount count: -1 34 Last checked: Mon Nov 3 13:44:20 2008 35 Check interval: 0 (<none>) 36 Reserved blocks uid: 0 (user root) 37 Reserved blocks gid: 0 (group root) 38 First inode: 11 39 Inode size: 128 40 Journal inode: 8 41 First orphan inode: 1540335 42 Default directory hash: tea 43 Directory Hash Seed: d91b5ece-e8b6-423b-95a4-6a36cc400a43 44 Journal backup: inode blocks 45 [root@pss1sitwls1a ~]# 46 47 48 这里先通过df -h命令获得一个某一块文件系统的名字,然后通过 tune2fs -l 去查看该文件系统上的supperblock的内容
文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。每一个文件对应一个inode,硬盘上有多少文件,就有多少个inode。
2. inode 的内容
查看inode的内容可以通过 stat 命令查看。 接下来的例子中,我们用touch创建一个文件,然后用stat 查看它的inode内容
-bash-3.2$ touch a -bash-3.2$ stat a File: `a' Size: 0 Blocks: 8 IO Block: 4096 regular empty file Device: 6802h/26626d Inode: 13389026 Links: 1 Access: (0640/-rw-r-----) Uid: (24041/ attlmw1) Gid: (24041/ attlmw1) Access: 2013-04-27 11:23:09.000000000 +0800 Modify: 2013-04-27 11:23:09.000000000 +0800 Change: 2013-04-27 11:23:09.000000000 +0800
这里要注意最后links, 如果这个文件有N个hard link,那么这里就会是n. 关于hard link更详细的内容,后面会有详细讲解。还有需要注意的地方是access modify change。他们代表了,文件的 访问时间,改变时间和修改时间。
access
这是文件的访问时间,比如我们用cat 去阅读一个文件,那么该文件的access time 就会被改成当前的时间。通过 ls -lu 这个命令同样可以看到文件访问时间。但是有一个问题,有些情况下即使你读了该文件,它的atime仍然不会改变。这也许是因为该文件是在一个nfs系统上,而nfs系统在mount的时候指定了noatime的选项。
modify
这是文件的修改时间,如果我们用编辑器修改了文件的内容,那么这部分的时间就会改变。 ls -l 默认显示的就是修改时间 mtime
change
这是文件的改变时间,准确的说是文件inode的改变时间。比如说我们用 chmod 选项修改了该文件的访问权限,那么这时只有 change time 改变。 我们用 ls -lc 也可以看到文件的ctime
有一个疑问是,既然access time 也是记录在inode上的,那么atime的改变就说明inode 有改变啊? 那么这时候ctime也应该修改了才对,但事实上,如果你用cat 去修改一个文件的atime,它的ctime是不会变的。比如
-bash-3.2$ touch a -bash-3.2$ stat a File: `a' Size: 5 Blocks: 16 IO Block: 4096 regular file Device: 6802h/26626d Inode: 2881233 Links: 1 Access: (0640/-rw-r-----) Uid: (24041/ attlmw1) Gid: ( 10/ wheel) Access: 2013-04-27 15:59:55.000000000 +0800 Modify: 2013-04-27 15:59:55.000000000 +0800 Change: 2013-04-27 15:59:55.000000000 +0800 -bash-3.2$ cat a haha -bash-3.2$ stat a File: `a' Size: 5 Blocks: 16 IO Block: 4096 regular file Device: 6802h/26626d Inode: 2881233 Links: 1 Access: (0640/-rw-r-----) Uid: (24041/ attlmw1) Gid: ( 10/ wheel) Access: 2013-04-27 15:59:59.000000000 +0800 Modify: 2013-04-27 15:59:55.000000000 +0800 Change: 2013-04-27 15:59:55.000000000 +0800
3. inode size
inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。
查看每个硬盘分区的inode总数和已经使用的数量,可以使用df命令。
$ df -i
注意,这一段是后加的 在unix情况下,如果是ufs可以用如下命令查看 -bash-3.00# df -F ufs -o i / Filesystem iused ifree %iused Mounted on /dev/md/dsk/d3 313429 1678379 16% / 如果是其它的文件类型如Vxfs,可以用下列命令。 -bash-3.00# df -t / / (/dev/md/dsk/d3 ): 3905190 blocks 1678379 files total: 33051508 blocks 1991808 files 其实,可以理解为不论什么文件系统都可以用-t查看inode
查看每个inode节点的大小,可以用如下命令:
$ dumpe2fs -h /dev/mapper/vg_bhrjira1-lv_root | grep "Inode size"
4. Inode作用及如何修改其信息
这部分包括这么几个内容:
- 移动或者操纵文件
- update
- hard link 和 soft link
- 如何修改其信息
移动或操纵文件
有些时候,有的文件名字中会包含一些不可见字符,这些文件可能是用程序生成的。既然是不可见字符,我们就没有办法通过文件的名字来操纵它,这时候就需要用inode 号码,每一个inode指向一个文件,所以通过inode号,我们可以定位文件。 通过ls -i 命令可以查看inode号码。
update
因为系统通过inode号码,识别运行中的文件,不通过文件名。更新的时候,新版文件以同样的文件名,生成一个新的inode,不会影响到运行中的文件。等到下一次运行这个软件的时候,文件名就自动指向新版文件,旧版文件的inode则被回收。
hardlink 和 soft link
学习节点就要了解hard link 和 soft link。 它们俩个跟inode息息相关。 我们先看 soft link。
首先通过命令创建一个文本文件file1 bash-3.2# echo aaaaaaaa>file1 看一下file1的inode信息,注意links的值为1 bash-3.2# stat file1 File: `file1' Size: 9 Blocks: 16 IO Block: 4096 regular file Device: 6802h/26626d Inode: 2881229 Links: 1 Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 1/ bin) Access: 2013-04-27 16:16:45.000000000 +0800 Modify: 2013-04-27 16:16:45.000000000 +0800 Change: 2013-04-27 16:16:45.000000000 +0800 我们用ln -s file1 soft_link_1这个命令为file1创建一个soft link bash-3.2# ln -s file1 soft_link_1 bash-3.2# bash-3.2# ls -l total 12 -rw-r----- 1 root bin 9 Apr 27 16:16 file1 lrwxrwxrwx 1 root bin 5 Apr 27 16:17 soft_link_1 -> file1 再看一下 file1 和soft_link_1的inode 信息 bash-3.2# stat file1 File: `file1' Size: 9 Blocks: 16 IO Block: 4096 regular file Device: 6802h/26626d Inode: 2881229 Links: 1 Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 1/ bin) Access: 2013-04-27 16:16:45.000000000 +0800 Modify: 2013-04-27 16:16:45.000000000 +0800 Change: 2013-04-27 16:16:45.000000000 +0800 bash-3.2# stat soft_link_1 File: `soft_link_1' -> `file1' Size: 5 Blocks: 8 IO Block: 4096 symbolic link Device: 6802h/26626d Inode: 2881231 Links: 1 Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 1/ bin) Access: 2013-04-27 16:17:23.000000000 +0800 Modify: 2013-04-27 16:17:09.000000000 +0800 Change: 2013-04-27 16:17:09.000000000 +0800 注意他们的links 的值都位1
上面创建的就是soft link,soft link是新创建一个链接文件,该链接文件指向源文件。因为是新创建了一个文件,所以soft link的链接文件具有独立的一个inode。 而且这种soft link可以说是单向性的,也就是说 soft_link_1指向 file1,而不是 file1 指向 soft_link_1,由于这种单向性,如果我们把 file1 删除掉 那么 soft_link_1虽然还存在,但是它指向的东西却没有了,比如:
没有删除file1之前, 对file1 和 soft_link_1的cat 都一样。 bash-3.2# cat file1 aaaaaaaa bash-3.2# cat soft_link_1 aaaaaaaa bash-3.2# mv file1 file2 bash-3.2# 删除了 file1后,soft_link_1在cat的时候会显示错误。 bash-3.2# ls -l total 12 -rw-r----- 1 root bin 9 Apr 27 16:16 file2 lrwxrwxrwx 1 root bin 5 Apr 27 16:17 soft_link_1 -> file1 bash-3.2# cat soft_link_1 cat: soft_link_1: No such file or directory
ok 简单总结一下,
- soft 是新生成一个链接文件
- 该链接文件具有独立的inode
- 该链接文件指向是单向的指向源文件。
那么 hard link是什么样的呢?
创建文件查看inode发现 links是1 bash-3.2# echo helloworld > file1 bash-3.2# stat file1 File: `file1' Size: 11 Blocks: 16 IO Block: 4096 regular file Device: 6802h/26626d Inode: 2881229 Links: 1 Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 1/ bin) Access: 2013-04-27 16:29:18.000000000 +0800 Modify: 2013-04-27 16:29:18.000000000 +0800 Change: 2013-04-27 16:29:18.000000000 +0800 创建hard link文件 hard_link_1 发现ls 和stat的内容都一样,并且links是2 bash-3.2# ln file1 hard_link_1 bash-3.2# bash-3.2# ls -l total 16 -rw-r----- 2 root bin 11 Apr 27 16:29 file1 -rw-r----- 2 root bin 11 Apr 27 16:29 hard_link_1 bash-3.2# stat file1 File: `file1' Size: 11 Blocks: 16 IO Block: 4096 regular file Device: 6802h/26626d Inode: 2881229 Links: 2 Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 1/ bin) Access: 2013-04-27 16:29:18.000000000 +0800 Modify: 2013-04-27 16:29:18.000000000 +0800 Change: 2013-04-27 16:29:34.000000000 +0800 bash-3.2# stat hard_link_1 File: `hard_link_1' Size: 11 Blocks: 16 IO Block: 4096 regular file Device: 6802h/26626d Inode: 2881229 Links: 2 Access: (0640/-rw-r-----) Uid: ( 0/ root) Gid: ( 1/ bin) Access: 2013-04-27 16:29:18.000000000 +0800 Modify: 2013-04-27 16:29:18.000000000 +0800 Change: 2013-04-27 16:29:34.000000000 +0800
为什么上面的 ls 和 stat 显示的信息都相同,并且links是2了呢? 首先我们回忆一下,读取文件的具体过程是,文件名 -> inode-> ->文件的具体内容。 这里的文件名其实只是当前目录文件的文件内容中的一个条目。 hard link 就是在指定的目录里增加这么一个条目,让其指向原来的inode。 在我们的例子中,我们是在当前的目录文件的文件内容中增加了 hard_link_1这么一个条目,让这个条目指向file1的 inode。 现在我们知道了, inode中的links是 指向它的文件名字的个数。由于hard link是这么样一个原理,所以它具有下面的特性:
- 删除hard link或者源文件之一只是删除了一个 文件名, 通过另外一个还可以访问文件。
- hard link不能跨文件系统,因为 他们用同一个inode
- 目录不可以创建
5. 几个命令
tune2fs - adjust tunable filesystem parameters on ext2/ext3 filesystems
dumpe2fs - dump ext2/ext3 filesystem information