久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

理解 Linux 的硬鏈接與軟鏈接

 Harrison.Ding 2013-07-29

理解 Linux 的硬鏈接與軟鏈接

從 inode 了解 Linux 文件系統(tǒng)

王 華東, 自由職業(yè)者

簡(jiǎn)介: 硬鏈接與軟鏈接是 Linux 文件系統(tǒng)中的一個(gè)重要概念,,其涉及文件系統(tǒng)中的索引節(jié)點(diǎn) (index node 又稱(chēng) inode),而索引節(jié)點(diǎn)對(duì)象是 Linux 虛擬文件系統(tǒng) (VFS) 的四個(gè)基本概念之一,。通過(guò)剖析硬鏈接與軟鏈接的聯(lián)系與區(qū)別,,我們可更好的了解 Linux 中 VFS 這一通用文件模型。并讓 Linux 普通用戶(hù)和系統(tǒng)管理員正確使用硬鏈接與軟鏈接,,幫助文件系統(tǒng)開(kāi)發(fā)者獲取 inode 的相關(guān)知識(shí),。

發(fā)布日期: 2012 年 12 月 20 日 
級(jí)別: 初級(jí) 
訪問(wèn)情況 : 8812 次瀏覽 
評(píng)論: 1 (查看 | 添加評(píng)論 - 登錄)

平均分 4 星 共 23 個(gè)評(píng)分 平均分 (23個(gè)評(píng)分)
為本文評(píng)分

Linux 的文件與目錄

現(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); 

硬鏈接與軟鏈接的聯(lián)系與區(qū)別

我們知道文件都有文件名與數(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)文件
圖 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)
圖 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 

鏈接相關(guān)命令

在 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 VFS

Linux 有著極其豐富的文件系統(tǒng),,大體上可分如下幾類(lèi):

  1. 網(wǎng)絡(luò)文件系統(tǒng),,如 nfs、cifs 等,;
  2. 磁盤(pán)文件系統(tǒng),,如 ext4、ext3 等,;
  3. 特殊文件系統(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)
圖 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ì)象之間的處理
圖 4. VFS 的對(duì)象之間的處理 

Linux 文件系統(tǒng)中的 inode

在 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 

結(jié)束語(yǔ)

本文最初描述了 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í)

討論

  • 加入 developerWorks 中文社區(qū),developerWorks 社區(qū)是一個(gè)面向全球 IT 專(zhuān)業(yè)人員,,可以提供博客,、書(shū)簽、wiki,、群組,、聯(lián)系、共享和協(xié)作等社區(qū)功能的專(zhuān)業(yè)社交網(wǎng)絡(luò)社區(qū),。

  • 加入 IBM 軟件下載與技術(shù)交流群組,,參與在線交流。

關(guān)于作者

王華東,,自由職業(yè)者,熟悉 Linux 系統(tǒng)管理,,對(duì) Linux 和 Open source 有濃厚的興趣,。通過(guò) [email protected] 可以和他聯(lián)系。


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶(hù)發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多