現(xiàn)代操作系統(tǒng)為解決信息能獨(dú)立于進(jìn)程之外被長(zhǎng)期存儲(chǔ)引入了文件,文件作為進(jìn)程創(chuàng)建信息的邏輯單元可被多個(gè)進(jìn)程并發(fā)使用,。在 UNIX 系統(tǒng)中,,操作系統(tǒng)為磁盤(pán)上的文本與圖像、鼠標(biāo)與鍵盤(pán)等輸入設(shè)備及網(wǎng)絡(luò)交互等 I/O 操作設(shè)計(jì)了一組通用 API,使他們被處理時(shí)均可統(tǒng)一使用字節(jié)流方式,。換言之,,UNIX 系統(tǒng)中除進(jìn)程之外的一切皆是文件,而 Linux 保持了這一特性,。為了便于文件的管理,Linux 還引入了目錄(有時(shí)亦被稱(chēng)為文件夾)這一概念,。目錄使文件可被分類(lèi)管理,,且目錄的引入使 Linux 的文件系統(tǒng)形成一個(gè)層級(jí)結(jié)構(gòu)的目錄樹(shù)。清單 1.所示的是普通 Linux 系統(tǒng)的頂層目錄結(jié)構(gòu),,其中 /dev 是存放了設(shè)備相關(guān)文件的目錄,。
清單 1. Linux 系統(tǒng)的頂層目錄結(jié)構(gòu)
/ 根目錄 ├── bin 存放用戶(hù)二進(jìn)制文件 ├── boot 存放內(nèi)核引導(dǎo)配置文件 ├── dev 存放設(shè)備文件 ├── etc 存放系統(tǒng)配置文件 ├── home 用戶(hù)主目錄 ├── lib 動(dòng)態(tài)共享庫(kù) ├── lost+found 文件系統(tǒng)恢復(fù)時(shí)的恢復(fù)文件 ├── media 可卸載存儲(chǔ)介質(zhì)掛載點(diǎn) ├── mnt 文件系統(tǒng)臨時(shí)掛載點(diǎn) ├── opt 附加的應(yīng)用程序包 ├── proc 系統(tǒng)內(nèi)存的映射目錄,,提供內(nèi)核與進(jìn)程信息 ├── root root 用戶(hù)主目錄 ├── sbin 存放系統(tǒng)二進(jìn)制文件 ├── srv 存放服務(wù)相關(guān)數(shù)據(jù) ├── sys sys 虛擬文件系統(tǒng)掛載點(diǎn) ├── tmp 存放臨時(shí)文件 ├── usr 存放用戶(hù)應(yīng)用程序 └── var 存放郵件,、系統(tǒng)日志等變化文件 |
Linux 與其他類(lèi) UNIX 系統(tǒng)一樣并不區(qū)分文件與目錄:目錄是記錄了其他文件名的文件。使用命令 mkdir 創(chuàng)建目錄時(shí),,若期望創(chuàng)建的目錄的名稱(chēng)與現(xiàn)有的文件名(或目錄名)重復(fù),,則會(huì)創(chuàng)建失敗。
# ls -F /usr/bin/zi* /usr/bin/zip* /usr/bin/zipgrep* /usr/bin/zipnote* /usr/bin/zipcloak* /usr/bin/zipinfo* /usr/bin/zipsplit* # mkdir -p /usr/bin/zip mkdir: cannot create directory `/usr/bin/zip': File exists |
Linux 將設(shè)備當(dāng)做文件進(jìn)行處理,,清單 2.展示了如何打開(kāi)設(shè)備文件 /dev/input/event5 并讀取文件內(nèi)容。文件 event5 表示一種輸入設(shè)備,,其可能是鼠標(biāo)或鍵盤(pán)等,。查看文件 /proc/bus/input/devices 可知 event5 對(duì)應(yīng)設(shè)備的類(lèi)型。設(shè)備文件 /dev/input/event5 使用 read() 以字符流的方式被讀取,。結(jié)構(gòu)體 input_event 被定義在內(nèi)核頭文件 linux/input.h 中,。
清單 2. 打開(kāi)并讀取設(shè)備文件
int fd; struct input_event ie; fd = open("/dev/input/event5", O_RDONLY); read(fd, &ie, sizeof(struct input_event)); printf("type = %d code = %d value = %d\n", ie.type, ie.code, ie.value); close(fd); |
我們知道文件都有文件名與數(shù)據(jù),,這在 Linux 上被分成兩個(gè)部分:用戶(hù)數(shù)據(jù) (user data) 與元數(shù)據(jù) (metadata),。用戶(hù)數(shù)據(jù),即文件數(shù)據(jù)塊 (data block),,數(shù)據(jù)塊是記錄文件真實(shí)內(nèi)容的地方,;而元數(shù)據(jù)則是文件的附加屬性,如文件大小,、創(chuàng)建時(shí)間,、所有者等信息。在 Linux 中,,元數(shù)據(jù)中的 inode 號(hào)(inode 是文件元數(shù)據(jù)的一部分但其并不包含文件名,,inode 號(hào)即索引節(jié)點(diǎn)號(hào))才是文件的唯一標(biāo)識(shí)而非文件名。文件名僅是為了方便人們的記憶和使用,系統(tǒng)或程序通過(guò) inode 號(hào)尋找正確的文件數(shù)據(jù)塊,。圖 1.展示了程序通過(guò)文件名獲取文件內(nèi)容的過(guò)程,。
圖 1. 通過(guò)文件名打開(kāi)文件
清單 3. 移動(dòng)或重命名文件
# stat /home/harris/source/glibc-2.16.0.tar.xz File: `/home/harris/source/glibc-2.16.0.tar.xz' Size: 9990512 Blocks: 19520 IO Block: 4096 regular file Device: 807h/2055d Inode: 2485677 Links: 1 Access: (0600/-rw-------) Uid: ( 1000/ harris) Gid: ( 1000/ harris) ... ... # mv /home/harris/source/glibc-2.16.0.tar.xz /home/harris/Desktop/glibc.tar.xz # ls -i -F /home/harris/Desktop/glibc.tar.xz 2485677 /home/harris/Desktop/glibc.tar.xz |
在 Linux 系統(tǒng)中查看 inode 號(hào)可使用命令 stat 或 ls -i(若是 AIX 系統(tǒng),,則使用命令 istat),。清單 3.中使用命令 mv 移動(dòng)并重命名文件 glibc-2.16.0.tar.xz,其結(jié)果不影響文件的用戶(hù)數(shù)據(jù)及 inode 號(hào),,文件移動(dòng)前后 inode 號(hào)均為:2485677,。
為解決文件的共享使用,Linux 系統(tǒng)引入了兩種鏈接:硬鏈接 (hard link) 與軟鏈接(又稱(chēng)符號(hào)鏈接,,即 soft link 或 symbolic link),。鏈接為 Linux 系統(tǒng)解決了文件的共享使用,還帶來(lái)了隱藏文件路徑,、增加權(quán)限安全及節(jié)省存儲(chǔ)等好處,。若一個(gè) inode 號(hào)對(duì)應(yīng)多個(gè)文件名,則稱(chēng)這些文件為硬鏈接,。換言之,,硬鏈接就是同一個(gè)文件使用了多個(gè)別名(見(jiàn) 圖 2.hard link 就是 file 的一個(gè)別名,他們有共同的 inode),。硬鏈接可由命令 link 或 ln 創(chuàng)建,。如下是對(duì)文件 oldfile 創(chuàng)建硬鏈接。
link oldfile newfile ln oldfile newfile |
由于硬鏈接是有著相同 inode 號(hào)僅文件名不同的文件,,因此硬鏈接存在以下幾點(diǎn)特性:
- 文件有相同的 inode 及 data block;
- 只能對(duì)已存在的文件進(jìn)行創(chuàng)建,;
- 不能交叉文件系統(tǒng)進(jìn)行硬鏈接的創(chuàng)建,;
- 不能對(duì)目錄進(jìn)行創(chuàng)建,只可對(duì)文件創(chuàng)建,;
- 刪除一個(gè)硬鏈接文件并不影響其他有相同 inode 號(hào)的文件,。
清單 4. 硬鏈接特性展示
# ls -li total 0 // 只能對(duì)已存在的文件創(chuàng)建硬連接 # link old.file hard.link link: cannot create link `hard.link' to `old.file': No such file or directory # echo "This is an original file" > old.file # cat old.file This is an original file # stat old.file File: `old.file' Size: 25 Blocks: 8 IO Block: 4096 regular file Device: 807h/2055d Inode: 660650 Links: 2 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) ... // 文件有相同的 inode 號(hào)以及 data block # link old.file hard.link | ls -li total 8 660650 -rw-r--r-- 2 root root 25 Sep 1 17:44 hard.link 660650 -rw-r--r-- 2 root root 25 Sep 1 17:44 old.file // 不能交叉文件系統(tǒng) # ln /dev/input/event5 /root/bfile.txt ln: failed to create hard link `/root/bfile.txt' => `/dev/input/event5': Invalid cross-device link // 不能對(duì)目錄進(jìn)行創(chuàng)建硬連接 # mkdir -p old.dir/test # ln old.dir/ hardlink.dir ln: `old.dir/': hard link not allowed for directory # ls -iF 660650 hard.link 657948 old.dir/ 660650 old.file |
文件 old.file 與 hard.link 有著相同的 inode 號(hào):660650 及文件權(quán)限,,inode 是隨著文件的存在而存在,,因此只有當(dāng)文件存在時(shí)才可創(chuàng)建硬鏈接,即當(dāng) inode 存在且鏈接計(jì)數(shù)器(link count)不為 0 時(shí),。inode 號(hào)僅在各文件系統(tǒng)下是唯一的,,當(dāng) Linux 掛載多個(gè)文件系統(tǒng)后將出現(xiàn) inode 號(hào)重復(fù)的現(xiàn)象(如 清單 5.所示,文件 t3.jpg,、sync 及 123.txt 并無(wú)關(guān)聯(lián),,卻有著相同的 inode 號(hào)),,因此硬鏈接創(chuàng)建時(shí)不可跨文件系統(tǒng)。設(shè)備文件目錄 /dev 使用的文件系統(tǒng)是 devtmpfs,,而 /root(與根目錄 / 一致)使用的是磁盤(pán)文件系統(tǒng) ext4,。清單 5.展示了使用命令 df 查看當(dāng)前系統(tǒng)中掛載的文件系統(tǒng)類(lèi)型、各文件系統(tǒng) inode 使用情況及文件系統(tǒng)掛載點(diǎn),。
清單 5. 查找有相同 inode 號(hào)的文件
# df -i --print-type Filesystem Type Inodes IUsed IFree IUse% Mounted on /dev/sda7 ext4 3147760 283483 2864277 10% / udev devtmpfs 496088 553 495535 1% /dev tmpfs tmpfs 499006 491 498515 1% /run none tmpfs 499006 3 499003 1% /run/lock none tmpfs 499006 15 498991 1% /run/shm /dev/sda6 fuseblk 74383900 4786 74379114 1% /media/DiskE /dev/sda8 fuseblk 29524592 19939 29504653 1% /media/DiskF # find / -inum 1114 /media/DiskE/Pictures/t3.jpg /media/DiskF/123.txt /bin/sync |
值得一提的是,Linux 系統(tǒng)存在 inode 號(hào)被用完但磁盤(pán)空間還有剩余的情況,。我們創(chuàng)建一個(gè) 5M 大小的 ext4 類(lèi)型的 mo.img 文件,,并將其掛載至目錄 /mnt。然后我們使用一個(gè) shell 腳本將掛載在 /mnt 下 ext4 文件系統(tǒng)的 indoe 耗盡(見(jiàn)清單 6.),。
清單 6. 測(cè)試文件系統(tǒng) inode 耗盡但仍有磁盤(pán)空間的情景
# dd if=/dev/zero of=mo.img bs=5120k count=1 # ls -lh mo.img -rw-r--r-- 1 root root 5.0M Sep 1 17:54 mo.img # mkfs -t ext4 -F ./mo.img ... OS type: Linux Block size=1024 (log=0) Fragment size=1024 (log=0) Stride=0 blocks, Stripe width=0 blocks 1280 inodes, 5120 blocks 256 blocks (5.00%) reserved for the super user ... ... Writing superblocks and filesystem accounting information: done # mount -o loop ./mo.img /mnt # cat /mnt/inode_test.sh #!/bin/bash for ((i = 1; ; i++)) do if [ $? -eq 0 ]; then echo "This is file_$i" > file_$i else exit 0 fi done # ./inode_test.sh ./inode_test.sh: line 6: file_1269: No space left on device # df -iT /mnt/; du -sh /mnt/ Filesystem Type Inodes IUsed IFree IUse% Mounted on /dev/loop0 ext4 1280 1280 0 100% /mnt 1.3M /mnt/ |
硬鏈接不能對(duì)目錄創(chuàng)建是受限于文件系統(tǒng)的設(shè)計(jì)(見(jiàn) 清單 4.對(duì)目錄創(chuàng)建硬鏈接將失?。,,F(xiàn) Linux 文件系統(tǒng)中的目錄均隱藏了兩個(gè)個(gè)特殊的目錄:當(dāng)前目錄(.)與父目錄(..)。查看這兩個(gè)特殊目錄的 inode 號(hào)可知其實(shí)這兩目錄就是兩個(gè)硬鏈接(注意目錄 /mnt/lost+found/ 的 inode 號(hào)),。若系統(tǒng)允許對(duì)目錄創(chuàng)建硬鏈接,,則會(huì)產(chǎn)生目錄環(huán)。
# ls -aliF /mnt/lost+found total 44 11 drwx------ 2 root root 12288 Sep 1 17:54 ./ 2 drwxr-xr-x 3 root root 31744 Sep 1 17:57 ../ # stat /mnt/lost+found/ File: `/mnt/lost+found/' Size: 12288 Blocks: 24 IO Block: 1024 directory Device: 700h/1792d Inode: 11 Links: 2 Access: (0700/drwx------) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2012-09-01 17:57:17.000000000 +0800 Modify: 2012-09-01 17:54:49.000000000 +0800 Change: 2012-09-01 17:54:49.000000000 +0800 Birth: - |
軟鏈接與硬鏈接不同,,若文件用戶(hù)數(shù)據(jù)塊中存放的內(nèi)容是另一文件的路徑名的指向,則該文件就是軟連接,。軟鏈接就是一個(gè)普通文件,,只是數(shù)據(jù)塊內(nèi)容有點(diǎn)特殊。軟鏈接有著自己的 inode 號(hào)以及用戶(hù)數(shù)據(jù)塊(見(jiàn) 圖 2.),。因此軟鏈接的創(chuàng)建與使用沒(méi)有類(lèi)似硬鏈接的諸多限制:
- 軟鏈接有自己的文件屬性及權(quán)限等,;
- 可對(duì)不存在的文件或目錄創(chuàng)建軟鏈接;
- 軟鏈接可交叉文件系統(tǒng),;
- 軟鏈接可對(duì)文件或目錄創(chuàng)建,;
- 創(chuàng)建軟鏈接時(shí),鏈接計(jì)數(shù) i_nlink 不會(huì)增加,;
- 刪除軟鏈接并不影響被指向的文件,,但若被指向的原文件被刪除,則相關(guān)軟連接被稱(chēng)為死鏈接(即 dangling link,,若被指向路徑文件被重新創(chuàng)建,,死鏈接可恢復(fù)為正常的軟鏈接)。
圖 2. 軟鏈接的訪問(wèn)
清單 7. 軟鏈接特性展示
# ls -li total 0 // 可對(duì)不存在的文件創(chuàng)建軟鏈接 # ln -s old.file soft.link # ls -liF total 0 789467 lrwxrwxrwx 1 root root 8 Sep 1 18:00 soft.link -> old.file // 由于被指向的文件不存在,,此時(shí)的軟鏈接 soft.link 就是死鏈接 # cat soft.link cat: soft.link: No such file or directory // 創(chuàng)建被指向的文件 old.file,,soft.link 恢復(fù)成正常的軟鏈接 # echo "This is an original file_A" >> old.file # cat soft.link This is an original file_A // 對(duì)不存在的目錄創(chuàng)建軟鏈接 # ln -s old.dir soft.link.dir # mkdir -p old.dir/test # tree . -F --inodes . ├── [ 789497] old.dir/ │ └── [ 789498] test/ ├── [ 789495] old.file ├── [ 789495] soft.link -> old.file └── [ 789497] soft.link.dir -> old.dir/ |
當(dāng)然軟鏈接的用戶(hù)數(shù)據(jù)也可以是另一個(gè)軟鏈接的路徑,其解析過(guò)程是遞歸的,。但需注意:軟鏈接創(chuàng)建時(shí)原文件的路徑指向使用絕對(duì)路徑較好,。使用相對(duì)路徑創(chuàng)建的軟鏈接被移動(dòng)后該軟鏈接文件將成為一個(gè)死鏈接(如下所示的軟鏈接 a 使用了相對(duì)路徑,因此不宜被移動(dòng)),,因?yàn)殒溄訑?shù)據(jù)塊中記錄的亦是相對(duì)路徑指向,。
$ ls -li total 2136 656627 lrwxrwxrwx 1 harris harris 8 Sep 1 14:37 a -> data.txt 656662 lrwxrwxrwx 1 harris harris 1 Sep 1 14:37 b -> a 656228 -rw------- 1 harris harris 2186738 Sep 1 14:37 data.txt 6 |
在 Linux 中查看當(dāng)前系統(tǒng)已掛著的文件系統(tǒng)類(lèi)型,,除上述使用的命令 df,,還可使用命令 mount 或查看文件 /proc/mounts。
# mount /dev/sda7 on / type ext4 (rw,errors=remount-ro) proc on /proc type proc (rw,noexec,nosuid,nodev) sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) ... ... none on /run/shm type tmpfs (rw,nosuid,nodev) |
命令 ls 或 stat 可幫助我們區(qū)分軟鏈接與其他文件并查看文件 inode 號(hào),,但較好的方式還是使用 find 命令,其不僅可查找某文件的軟鏈接,,還可以用于查找相同 inode 的所有硬鏈接,。(見(jiàn)清單 8.)
清單 8. 使用命令 find 查找軟鏈接與硬鏈接
// 查找在路徑 /home 下的文件 data.txt 的軟鏈接 # find /home -lname data.txt /home/harris/debug/test2/a // 查看路徑 /home 有相同 inode 的所有硬鏈接 # find /home -samefile /home/harris/debug/test3/old.file /home/harris/debug/test3/hard.link /home/harris/debug/test3/old.file # find /home -inum 660650 /home/harris/debug/test3/hard.link /home/harris/debug/test3/old.file // 列出路徑 /home/harris/debug/ 下的所有軟鏈接文件 # find /home/harris/debug/ -type l -ls 656662 0 lrwxrwxrwx 1 harris harris 1 Sep 1 14:37 /home/harris/debug/test2/b -> a 656627 0 lrwxrwxrwx 1 harris harris 8 Sep 1 14:37 /home/harris/debug/test2/a -> data.txt 789467 0 lrwxrwxrwx 1 root root 8 Sep 1 18:00 /home/harris/debug/test/soft.link -> old.file 789496 0 lrwxrwxrwx 1 root root 7 Sep 1 18:01 /home/harris/debug/test/soft.link.dir -> old.dir |
系統(tǒng)根據(jù)磁盤(pán)的大小默認(rèn)設(shè)定了 inode 的值(見(jiàn)清單 9.),,如若必要,,可在格式文件系統(tǒng)前對(duì)該值進(jìn)行修改。如鍵入命令 mkfs -t ext4 -I 512
/
dev/sda4,,
將使磁盤(pán)設(shè)備 /dev/sda4 格式成 inode 大小是 512 字節(jié)的 ext4 文件系統(tǒng),。
清單 9. 查看系統(tǒng)的 inode 值
// 查看磁盤(pán)分區(qū) /dev/sda7 上的 inode 值 # dumpe2fs -h /dev/sda7 | grep "Inode size" dumpe2fs 1.42 (29-Nov-2011) Inode size: 256 # tune2fs -l /dev/sda7 | grep "Inode size" Inode size: 256 |
Linux 有著極其豐富的文件系統(tǒng),,大體上可分如下幾類(lèi):
- 網(wǎng)絡(luò)文件系統(tǒng),,如 nfs、cifs 等,;
- 磁盤(pán)文件系統(tǒng),,如 ext4、ext3 等,;
- 特殊文件系統(tǒng),,如 proc、sysfs,、ramfs,、tmpfs 等。
實(shí)現(xiàn)以上這些文件系統(tǒng)并在 Linux 下共存的基礎(chǔ)就是 Linux VFS(Virtual File System 又稱(chēng) Virtual Filesystem Switch),,即虛擬文件系統(tǒng),。VFS 作為一個(gè)通用的文件系統(tǒng),抽象了文件系統(tǒng)的四個(gè)基本概念:文件,、目錄項(xiàng) (dentry),、索引節(jié)點(diǎn) (inode) 及掛載點(diǎn),,其在內(nèi)核中為用戶(hù)空間層的文件系統(tǒng)提供了相關(guān)的接口(見(jiàn) 圖 3.所示 VFS 在 Linux 系統(tǒng)的架構(gòu))。VFS 實(shí)現(xiàn)了 open(),、read() 等系統(tǒng)調(diào)并使得 cp 等用戶(hù)空間程序可跨文件系統(tǒng),。VFS 真正實(shí)現(xiàn)了上述內(nèi)容中:在 Linux 中除進(jìn)程之外一切皆是文件。
圖 3. VFS 在系統(tǒng)中的架構(gòu)
Linux VFS 存在四個(gè)基本對(duì)象:超級(jí)塊對(duì)象 (superblock object),、索引節(jié)點(diǎn)對(duì)象 (inode object),、目錄項(xiàng)對(duì)象 (dentry object) 及文件對(duì)象 (file object)。超級(jí)塊對(duì)象代表一個(gè)已安裝的文件系統(tǒng),;索引節(jié)點(diǎn)對(duì)象代表一個(gè)文件,;目錄項(xiàng)對(duì)象代表一個(gè)目錄項(xiàng),如設(shè)備文件 event5 在路徑 /dev/input/event5 中,,其存在四個(gè)目錄項(xiàng)對(duì)象:/ ,、dev/ 、input/ 及 event5,。文件對(duì)象代表由進(jìn)程打開(kāi)的文件,。這四個(gè)對(duì)象與進(jìn)程及磁盤(pán)文件間的關(guān)系如圖 4. 所示,其中 d_inode 即為硬鏈接,。為文件路徑的快速解析,Linux VFS 設(shè)計(jì)了目錄項(xiàng)緩存(Directory Entry Cache,,即 dcache),。
圖 4. VFS 的對(duì)象之間的處理
在 Linux 中,索引節(jié)點(diǎn)結(jié)構(gòu)存在于系統(tǒng)內(nèi)存及磁盤(pán),,其可區(qū)分成 VFS inode 與實(shí)際文件系統(tǒng)的 inode,。VFS inode 作為實(shí)際文件系統(tǒng)中 inode 的抽象,定義了結(jié)構(gòu)體 inode 與其相關(guān)的操作 inode_operations(見(jiàn)內(nèi)核源碼 include/linux/fs.h),。
清單 10. VFS 中的 inode 與 inode_operations 結(jié)構(gòu)體
struct inode { ... const struct inode_operations *i_op; // 索引節(jié)點(diǎn)操作 unsigned long i_ino; // 索引節(jié)點(diǎn)號(hào) atomic_t i_count; // 引用計(jì)數(shù)器 unsigned int i_nlink; // 硬鏈接數(shù)目 ... } struct inode_operations { ... int (*create) (struct inode *,struct dentry *,int, struct nameidata *); int (*link) (struct dentry *,struct inode *,struct dentry *); int (*unlink) (struct inode *,struct dentry *); int (*symlink) (struct inode *,struct dentry *,const char *); int (*mkdir) (struct inode *,struct dentry *,int); int (*rmdir) (struct inode *,struct dentry *); ... } |
如清單 10. 所見(jiàn),每個(gè)文件存在兩個(gè)計(jì)數(shù)器:i_count 與 i_nlink,,即引用計(jì)數(shù)與硬鏈接計(jì)數(shù),。結(jié)構(gòu)體 inode 中的 i_count 用于跟蹤文件被訪問(wèn)的數(shù)量,而 i_nlink 則是上述使用 ls -l 等命令查看到的文件硬鏈接數(shù),?;蛘哒f(shuō) i_count 跟蹤文件在內(nèi)存中的情況,而 i_nlink 則是磁盤(pán)計(jì)數(shù)器,。當(dāng)文件被刪除時(shí),,則 i_nlink 先被設(shè)置成 0。文件的這兩個(gè)計(jì)數(shù)器使得 Linux 系統(tǒng)升級(jí)或程序更新變的容易,。系統(tǒng)或程序可在不關(guān)閉的情況下(即文件 i_count 不為 0),,將新文件以同樣的文件名進(jìn)行替換,,新文件有自己的 inode 及 data block,舊文件會(huì)在相關(guān)進(jìn)程關(guān)閉后被完整的刪除,。
清單 11. 文件系統(tǒng) ext4 中的 inode
struct ext4_inode { ... __le32 i_atime; // 文件內(nèi)容最后一次訪問(wèn)時(shí)間 __le32 i_ctime; // inode 修改時(shí)間 __le32 i_mtime; // 文件內(nèi)容最后一次修改時(shí)間 __le16 i_links_count; // 硬鏈接計(jì)數(shù) __le32 i_blocks_lo; // Block 計(jì)數(shù) __le32 i_block[EXT4_N_BLOCKS]; // 指向具體的 block ... }; |
清單 11. 展示的是文件系統(tǒng) ext4 中對(duì) inode 的定義(見(jiàn)內(nèi)核源碼 fs/ext4/ext4.h)。其中三個(gè)時(shí)間的定義可對(duì)應(yīng)與命令 stat 中查看到三個(gè)時(shí)間,。i_links_count 不僅用于文件的硬鏈接計(jì)數(shù),,也用于目錄的子目錄數(shù)跟蹤(目錄并不顯示硬鏈接數(shù),命令 ls -ld 查看到的是子目錄數(shù)),。由于文件系統(tǒng) ext3 對(duì) i_links_count 有限制,,其最大數(shù)為:32000(該限制在 ext4 中被取消)。嘗試在 ext3 文件系統(tǒng)上驗(yàn)證目錄子目錄及普通文件硬鏈接最大數(shù)可見(jiàn) 清單 12. 的錯(cuò)誤信息,。因此實(shí)際文件系統(tǒng)的 inode 之間及與 VFS inode 相較是有差異的,。
清單 12. 文件系統(tǒng) ext3 中 i_links_count 的限制
# ./dirtest.sh mkdir: cannot create directory `dir_31999': Too many links # ./linkcount.sh ln: failed to create hard link to `old.file': Too many links |
本文最初描述了 Linux 系統(tǒng)中文件與目錄被引入的原因及 Linux 處理文件的方式,,然后我們通過(guò)區(qū)分硬鏈接與軟鏈接的不同,,了解 Linux 中的索引節(jié)點(diǎn)的相關(guān)知識(shí),并以此引出了 inode 的結(jié)構(gòu)體,。索引節(jié)點(diǎn)結(jié)構(gòu)體存在在于 Linux VFS 以及實(shí)際文件系統(tǒng)中,,VFS 作為通用文件模型是 Linux 中“一切皆是文件”實(shí)現(xiàn)的基礎(chǔ)。文章并未深入 Linux VFS,,也沒(méi)涉及實(shí)際文件系統(tǒng)的實(shí)現(xiàn),,文章只是從 inode 了解 Linux 的文件系統(tǒng)的相關(guān)內(nèi)容。若想深入文件系統(tǒng)的內(nèi)容,,查看內(nèi)核文檔 Documentation/filesystems/ 是一個(gè)不錯(cuò)的方式,。
學(xué)習(xí)
- 查看文章“學(xué)習(xí) Linux,101: 文件和目錄管理”,,熟悉 Linux 的文件和目錄,。
- 查看文章“學(xué)習(xí) Linux,101: 創(chuàng)建和更改硬鏈接和符號(hào)鏈接”,,掌握與硬鏈接和軟鏈接相關(guān)的命令,。
- 查看 wiki 上“Hard link”、“Symbolic link”及“inode”等內(nèi)容,。
- 查閱 symlink(7)的 man 手冊(cè),,了解 Linux 中的軟鏈接。
- 查看文章“Q & A: The difference between hard and soft links”,,了解硬鏈接與軟鏈接的區(qū)別,。
- 查看文章“In UNIX Everything is a File”,了解 UNIX 中除進(jìn)程外一切皆是文件,。
- 查看文章“Linux 虛擬系統(tǒng)文件交換器剖析”與“Linux 文件系統(tǒng)剖析”,,獲取 Linux 虛擬文件系統(tǒng) (Linux VFS) 相關(guān)知識(shí),。
- 查看文章“解析 Linux 中的 VFS 文件系統(tǒng)機(jī)制”,深入理解實(shí)例一個(gè)文件系統(tǒng)系統(tǒng)的過(guò)程,。
- 查看文章“對(duì)話 UNIX: 關(guān)于 inode”,,了解 inode 相關(guān)內(nèi)容。
- 查看文章“Linux 文件系統(tǒng)中元數(shù)據(jù)使用計(jì)數(shù)的機(jī)制”,,了解 Linux 對(duì) dentry 和 inode 的計(jì)數(shù)操作,。
- 查看內(nèi)核源碼文件 Documentation/filesystems/ext4.txt,了解文件系統(tǒng) ext4 的相關(guān)內(nèi)容,。
- 在 developerWorks Linux 專(zhuān)區(qū) 尋找為 Linux 開(kāi)發(fā)人員(包括 Linux 新手入門(mén))準(zhǔn)備的更多參考資料,,查閱我們 最受歡迎的文章和教程。
- 在 developerWorks 上查閱所有 Linux 技巧 和 Linux 教程,。
- 隨時(shí)關(guān)注 developerWorks 技術(shù)活動(dòng)和網(wǎng)絡(luò)廣播,。
討論
- 加入 developerWorks 中文社區(qū),developerWorks 社區(qū)是一個(gè)面向全球 IT 專(zhuān)業(yè)人員,,可以提供博客,、書(shū)簽、wiki,、群組,、聯(lián)系、共享和協(xié)作等社區(qū)功能的專(zhuān)業(yè)社交網(wǎng)絡(luò)社區(qū),。
- 加入 IBM 軟件下載與技術(shù)交流群組,,參與在線交流。
王華東,,自由職業(yè)者,熟悉 Linux 系統(tǒng)管理,,對(duì) Linux 和 Open source 有濃厚的興趣,。通過(guò) [email protected] 可以和他聯(lián)系。