2021-05-12 14:32:11
Linux檔案系統之inode與軟硬連線
一、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則被回收。
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2017-02/140311p2.htm
相關文章