歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux文件系統之inode與軟硬連接

Linux文件系統之inode與軟硬連接

日期:2017/2/28 13:43:47   编辑:Linux教程

一、inode是什麼?

理解inode,要從文件儲存說起。

文件儲存在硬盤上,硬盤的最小存儲單位叫做"扇區"(Sector)。每個扇區儲存512字節(相當於0.5KB)。

操作系統讀取硬盤的時候,不會一個個扇區地讀取,這樣效率太低,而是一次性連續讀取多個扇區,即一次性讀取一個"塊"(block)。這種由多個扇區組成的"塊",是文件存取的最小單位。"塊"的大小,最常見的是4KB,即連續八個 sector組成一個 block。

文件數據都儲存在"塊"中,那麼很顯然,我們還必須找到一個地方儲存文件的元信息,比如文件的創建者、文件的創建日期、文件的大小等等。這種儲存文件元信息的區域就叫做inode,中文譯名為"索引節點"。

每一個文件都有對應的inode,裡面包含了與該文件有關的一些信息。

二、inode的內容

inode包含文件的元信息,具體來說有以下內容:

  * 文件的字節數

  * 文件擁有者的User ID

  * 文件的Group ID

  * 文件的讀、寫、執行權限

  * 文件的時間戳,共有三個:ctime指inode上一次變動的時間,mtime指文件內容上一次變動的時間,atime指文件上一次打開的時間。

  * 鏈接數,即有多少文件名指向這個inode

  * 文件數據block的位置

inode結構圖:

inode要記錄的數據非常多,但偏偏只有128bytes而已,而inode記錄一個block號碼要花掉4bytes,假設我一個文件有400MB,且每個block為4KB時,那麼至少也要10萬條block號碼的記錄。inode哪有那麼多可記錄的信息?為此,我們的系統聰明的將inode記錄block號碼的區域定義為12個直接,1個雙間接,一個3間接記錄區 這樣子inode能夠指定多少個block呢?我們以較小的1KB的block來說明:

(1) 12個直接指向   12*1K = 12K
(2)每條block號碼的記錄會花去4bytes,因此1K的block大小能夠記錄256條記錄。所以間接地256*1K = 256K
(3)雙間接 256*256*1K = 256^2K
 (4)三間接     256*256*256*1K = 256^3K

總額:12+256+256*256+256+256+256=16GB 此時我們知道當文件系統將block格式化為1K大小時,能夠容納的最大文件為16GB,比較一下文件系統的限制表的結果可以發現結果是一致的。但是這個方法不能夠用在2K及4K的block大小的計算中,因為2K的block將會受到Ext2文件系統本身的限制,所以計算的結果會有不符合 。

可以用stat命令,查看某個文件的inode信息:

[root@localhost ~]# stat anaconda-ks.cfg 
  File: `anaconda-ks.cfg'
  Size: 1874            Blocks: 8          IO Block: 4096   regular file
Device: fd00h/64768d    Inode: 131083      Links: 1
Access: (0600/-rw-------)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-12-29 16:35:26.562699425 +0800
Modify: 2016-12-26 15:29:45.735999937 +0800
Change: 2016-12-26 15:29:49.750999936 +0800

總之,除了文件名以外的所有文件信息,都存在inode之中。至於為什麼沒有文件名,下文會有詳細解釋。

三、inode的大小

inode也會消耗硬盤空間,所以硬盤格式化的時候,操作系統自動將硬盤分成兩個區域。一個是數據區,存放文件數據;另一個是inode區(inode table),存放inode所包含的信息。

每個inode節點的大小,一般是128字節或256字節。inode節點的總數,在格式化時就給定,一般是每1KB或每2KB就設置一個inode。假定在一塊1GB的硬盤中,每個inode節點的大小為128字節,每1KB就設置一個inode,那麼inode table的大小就會達到128MB,占整塊硬盤的12.8%。

查看每個硬盤分區的inode總數和已經使用的數量,可以使用df命令:

[root@localhost ~]# df -i
Filesystem            Inodes IUsed   IFree IUse% Mounted on
/dev/mapper/vg0-root 1310720  7556 1303164    1% /
tmpfs                 125517     1  125516    1% /dev/shm
/dev/sda1              51200    38   51162    1% /boot
/dev/mapper/vg0-usr   655360 25449  629911    4% /usr
/dev/mapper/vg0-var  1310720  1132 1309588    1% /var

查看每個inode節點的大小,可以用如下命令:

[root@localhost ~]# dumpe2fs -h /dev/sda1 | grep 'Inode size' 
dumpe2fs 1.41.12 (17-May-2010)
Inode size:               128

或者 # tune2fs -l /dev/sda7 | grep "Inode size" Inode size: 256

由於每個文件都必須有一個inode,因此有可能發生inode已經用光,但是硬盤還未存滿的情況。這時,就無法在硬盤上創建新文件。

四、inode號碼

每個inode都有一個號碼,操作系統用inode號碼來識別不同的文件。

這裡值得重復一遍,Unix/Linux系統內部不使用文件名,而使用inode號碼來識別文件。對於系統來說,文件名只是inode號碼便於識別的別稱或者綽號。

表面上,用戶通過文件名,打開文件。實際上,系統內部這個過程分成三步:首先,系統找到這個文件名對應的inode號碼;其次,通過inode號碼,獲取inode信息;最後,根據inode信息,找到文件數據所在block,讀出數據。

使用ls -i命令,可以看到文件名對應的inode號碼:

[root@localhost ~]# ls -i anaconda-ks.cfg 
131083 anaconda-ks.cfg

五、目錄文件

Unix/Linux系統中,目錄(directory)也是一種文件。打開目錄,實際上就是打開目錄文件。

目錄文件的結構非常簡單,就是一系列目錄項(dirent)的列表。每個目錄項,由兩部分組成:所包含文件的文件名,以及該文件名對應的inode號碼。

inode與目錄關系圖:

ls命令只列出目錄文件中的所有文件名:

[root@localhost ~]# ls /var/log
anaconda.ifcfg.log    anaconda.yum.log  cron        maillog   secure
anaconda.log          audit             dmesg       messages  spooler
anaconda.program.log  boot.log          dmesg.old   ntpstats  tallylog
anaconda.storage.log  btmp              dracut.log  prelink   wtmp
anaconda.syslog       ConsoleKit        lastlog     sa        yum.log

ls -i命令列出整個目錄文件,即文件名和inode號碼:

[root@localhost ~]# ls -i /var/log
524312 anaconda.ifcfg.log    524293 ConsoleKit  524305 prelink
524308 anaconda.log          524322 cron        524302 sa
524310 anaconda.program.log  524318 dmesg       524299 secure
524311 anaconda.storage.log  524314 dmesg.old   524301 spooler
524309 anaconda.syslog       524307 dracut.log  524292 tallylog
524313 anaconda.yum.log      524294 lastlog     524295 wtmp
524306 audit                 524300 maillog     524342 yum.log
524319 boot.log              524298 messages
524296 btmp                  524303 ntpstats

如果要查看文件的詳細信息,就必須根據inode號碼,訪問inode節點,讀取信息。ls -l命令列出文件的詳細信息。

[root@localhost ~]# ls -l /var/log
total 1328
-rw-------. 1 root root   2646 Dec 26 15:29 anaconda.ifcfg.log
-rw-------. 1 root root  23138 Dec 26 15:29 anaconda.log
-rw-------. 1 root root  45436 Dec 26 15:29 anaconda.program.log
-rw-------. 1 root root 113674 Dec 26 15:29 anaconda.storage.log
...

理解了上面這些知識,就能理解目錄的權限。目錄文件的讀權限(r)和寫權限(w),都是針對目錄文件本身。由於目錄文件內只有文件名和inode號碼,所以如果只有讀權限,只能獲取文件名,無法獲取其他信息,因為其他信息都儲存在inode節點中,而讀取inode節點內的信息需要目錄文件的執行權限(x)。

六、inode的特殊作用

由於inode號碼與文件名分離,這種機制導致了一些Unix/Linux系統特有的現象。

1.有時,文件名包含特殊字符,無法正常刪除。這時,直接刪除inode節點,就能起到刪除文件的作用。

  

2.打開一個文件以後,系統就以inode號碼來識別這個文件,不再考慮文件名。因此,通常來說,系統無法從inode號碼得知文件名。   

3.cp與inode:分配一個空閒的inode號,在inode表中生成新條目在目錄中創建一個目錄項,將名稱與inode編號關聯拷貝數據生成新的文件。

4.rm與inode:鏈接數遞減,從而釋放的inode號可以被重用把數據塊放空閒列表中刪除目錄項數據實際上不會馬上被刪除,但當另一個文件使用數據塊時將被覆蓋。

5.mv與inode:如果mv命令的目標和源在相同的文件系統,作為mv 命令用新的文件名創建對應新的目錄項刪除舊目錄條目對應的舊的文件名不影響inode表(除時間戳)或磁盤上的數據位置:沒有數據被移動!如果目標和源在一個不同的文件系統, mv相當於cp和rm。如果mv命令的目標和源在相同的文件系統,作為mv 命令用新的文件名創建對應新的目錄項刪除舊目錄條目對應的舊的文件名不影響inode表(除時間戳)或磁盤上的數據位置:沒有數據被移動!如果目標和源在一個不同的文件系統, mv相當於cp和rm。

注:第3點使得軟件更新變得簡單,可以在不關閉軟件的情況下進行更新,不需要重啟。因為系統通過inode號碼,識別運行中的文件,不通過文件名。更新的時候,新版文件以同樣的文件名,生成一個新的inode,不會影響到運行中的文件。等到下一次運行這個軟件的時候,文件名就自動指向新版文件,舊版文件的inode則被回收。

Copyright © Linux教程網 All Rights Reserved