從文件系統的角度區分硬鏈接與軟連接

摘要

鏈接的目的是爲了實現文件共享

同一個文件系統中如果兩個文件(目錄也是文件)具有相同的inode號碼,那麼就稱它們是“硬鏈接”關係。這些具有硬鏈接關係的文件系統對象名字具有相同的inode號碼,彼此是平等的。即首個被創建的文件並沒有特殊的地位。

軟鏈接有着自己的inode號以及用戶數據塊。只不過用戶數據塊中存放的內容是被鏈接文件的路徑。當用戶訪問這個文件時,系統會根據所存儲的路徑,層層找到被鏈接的文件,如果這個文件已經被刪除了,則會提示No such file or directory。

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

1 引言

本人不喜看書,因爲低效。看大半部分便草草結束。所以從湯小丹《計算機操作系統原理》,到鄭剛的《操作系統 真象還原》,再到Tanenbaum的《現代操作系統》,才理解鳥哥書上(該書本處圖不看也罷)關於硬鏈接與軟連接的區別。
網上很多文章挺好,但是“缺少圖片”。文字描述,有時候不好理解。故結合多篇文章與上面書籍中的相關內容,揉在一起,產生了下面的內容:從文件系統的角度區分硬鏈接與軟連接。

2 文件系統的相關概念

2.1 創建文件系統的目的

首先,爲什麼需要文件系統?(只有需要,human才創建它,當然不是爲了好玩)

現代操作系統爲解決信息能獨立於進程之外被長期存儲引入了文件,文件作爲進程創建信息的邏輯單元可被多個進程併發使用。在 UNIX 系統中,操作系統爲磁盤上的文本與圖像、鼠標與鍵盤等輸入設備及網絡交互等 I/O 操作設計了一組通用 API,使他們被處理時均可統一使用字節流方式。換言之,UNIX 系統中除進程之外的一切皆是文件,而 Linux 保持了這一特性。爲了便於文件的管理,Linux 還引入了目錄(有時亦被稱爲文件夾)這一概念。目錄使文件可被分類管理,且目錄的引入使 Linux 的文件系統形成一個層級結構的目錄樹。

其實往簡單點說:因爲硬盤能長期存儲,爲了管理硬盤,產生了文件系統。
操做系統提取處理器的概念來建立進程的抽象,提取物理存儲器(內存)的概念來建立進程(虛擬)地址空間的抽象;從硬盤中建立抽象----文件,來解決信息長久存儲/調用等問題。

硬盤上的文件由進程創建。硬盤上的文件使用之前,要被進程加載進入內存。
而“文件描述符,進程,文件之間的關係”,可以參看下面的鏈接。由於和本篇文章的關係不大,咱們不做介紹。(咱也不清楚,咱也不敢問。因爲這裏面最起碼有硬盤驅動得事。)
文件描述符(File Descriptor)簡介
Linux文件描述符到底是什麼?
每個Unix進程都有的三個標準POSIX文件描述符

思考一個問題:內存和硬盤都爲存儲介質,爲什麼建立了不同的抽象?(一個爲虛擬地址空間,一個爲文件系統)
在這裏插入圖片描述

2.2 文件系統的概念簡介

硬鏈接與軟連接的區別呢?爲啥還在說文件系統。糊你一臉。
無奈啊,從文件系統的角度,可以很好的理解硬鏈接與軟連接。所以咱們還得接着扛。
硬盤可以長久保存信息。咱們需要硬盤來保存文件。
所以,咱們如何在硬盤上組織文件系統,使得硬盤可以合理得存儲文件,便於增刪改查?

前提:我們現在考慮的範圍,只有一個文件系統(不考慮虛擬文件系統(VFS))
能力有限,無法引導思考,咱們直接看文件系統得佈局。(圖片來自《操作系統 真象還原》)
在這裏插入圖片描述
關於引導,主分區,邏輯分區之類咱們跳過。具體情況,我不知道,下面引用wiki-inode的一段話,來說明上面這張圖的目的(di)。(當然,很明顯,wiki這段解釋,很不嚴謹。能力有限,不能修正)

文件系統創建(格式化)時,就把存儲區域分爲兩大連續的存儲區域。一個用來保存文件系統對象的元信息數據,這是由inode組成的表,每個inode默認是256字節或者128字節。另一個用來保存“文件系統對象”的內容數據,劃分爲512字節的扇區,以及由8個扇區組成的4K字節的塊(block)。塊是讀寫時的基本單位。一個文件系統的inode的總數是固定的。這限制了該文件系統所能存儲的文件系統對象的總數目。典型的實現下,所有inode佔用了文件系統1%左右的存儲容量。

上面可知:文件 = 元信息(inode) + 內容數據(blocks)。
元信息可以包含文件的字節數,文件擁有者,文件讀、寫、執行權限、時間戳、鏈接數、blocks位置。

那目錄如何處理?
首先明確一點,目錄也是文件。不管文件是普通文件,還是目錄文件,它總會存在於某個目錄中,所有的普通文件或目錄文件都存在於根目錄’/'之下,根目錄是所有目錄的父目錄。目錄下面有文件,也可以有目錄。目錄也是文件。一個目錄數據塊中 目錄項數==文件數
在這裏插入圖片描述
如上圖所示。從根目錄出發。文件 = 元信息(inode) + 內容數據(blocks)
根目錄文件,有個inode。裏面除了相關信息之外,包含 若干個目錄項。每個目錄項對應一個文件。如果該文件是一個非目錄文件,直接找到文件對應的inode編號,然後找到對應的block。如果是一個目錄文件,找到對應的inode編號,如果有執行(x)權限,則可以打開目錄,進入新的目錄。以此類推。

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

2.3文件共享

文件共享使多個用戶(進程)共享同一份文件,系統中只需保留該文件的一份副本。如果系統不能提供共享功能,那麼每個需要該文件的用戶都要有各自的副本,會造成對存儲空間的極大浪費。

爲解決文件的共享使用,Linux 系統引入了兩種鏈接:硬鏈接 (hard link) 與軟鏈接(又稱符號鏈接,即 soft link 或 symbolic link)。鏈接爲 Linux 系統解決了文件的共享使用,還帶來了隱藏文件路徑、增加權限安全及節省存儲等好處。

圖片來自《現代操作系統》,4.3.4文件共享。
下面這張圖,方框表示目錄,圓圈表示文件。它僅僅是一個示意圖,表文件共享即一個文件只有一個副本,但是可以放在不同的目錄下,通過不同的路徑訪問。

在這裏插入圖片描述
那我們如何通過鏈接實現文件共享?

2.3.1 硬鏈接實現文件共享

在目錄中增添新的目錄項。目錄項中存儲被鏈接文件的inode。
所以:若一個 inode 號對應多個文件名,則稱這些文件爲硬鏈接。換言之,硬鏈接就是同一個文件使用了多個別名。
在這裏插入圖片描述

2.3.2 軟連接實現文件共享

軟鏈接與硬鏈接不同,若文件用戶數據塊中存放的內容是另一文件的路徑名的指向,則該文件就是軟連接。軟鏈接就是一個普通文件,只是數據塊內容有點特殊。軟鏈接有着自己的 inode 號以及用戶數據塊
在這裏插入圖片描述

2.3.3 硬/軟鏈接特性對比

由於硬鏈接是有着相同 inode 號僅文件名不同的文件,因此硬鏈接存在以下幾點特性:

  • 文件有相同的 inode 及 data block;
  • 只能對已存在的文件進行創建;
  • 不能交叉文件系統進行硬鏈接的創建;
  • 不能對目錄進行創建,只可對文件創建;不能跨文件系統;
  • 刪除一個硬鏈接文件並不影響其他有相同 inode 號的文件。

由於軟連接是一個存儲着被鏈接文件的特殊文件,所以軟連接具有一下特性:

  • 軟鏈接有自己的文件屬性及權限等;
  • 可對不存在的文件或目錄創建軟鏈接;
  • 軟鏈接可交叉文件系統;
  • 軟鏈接可對文件或目錄創建;
  • 創建軟鏈接時,鏈接計數 i_nlink 不會增加;
  • 刪除軟鏈接並不影響被指向的文件,但若被指向的原文件被刪除,則相關軟連接被稱爲死鏈接(即 dangling link,若被指向路徑文件被重新創建,死鏈接可恢復爲正常的軟鏈接)。

2.3.4爲什麼硬鏈接不能指向目錄

因爲硬鏈接文件和普通文件一樣,他們地位平等,系統無法區分(.和…除外)。
如果硬鏈接的對象,是普通文件,如上圖所示,沒有什麼問題。
但如果硬鏈接的對象,是目錄。比如這個目錄是自身,即目錄項中的存儲的inode節點是自身。那麼在樹形的目錄結構中,遍歷的時候,會產生死循環。因爲圖結構中有自迴環。同理,如果鏈接的目錄不是自身,就更加複雜。
這也是:爲什麼 允許目錄的硬鏈接可能會打破文件系統的有向無環圖結構。
而,軟連接不會打破有向無環圖。因爲因爲鏈接多產生一個文件,而且系統能夠識別出它的屬性(l)。
詳細內容可以參考:多角度分析爲什麼 Linux 的硬連接不能指向目錄

2.3.4 linux操作系統鏈接操作

上面只涉及理論知識,沒有具體的操作佐證。因爲我想操作挺簡單。
Linux建立文件硬鏈接和軟鏈接,王海軍老師告訴你兩種鏈接之區別(視頻)
理解inode --阮一峯
5分鐘讓你明白“軟鏈接”和“硬鏈接”的區別
理解 Linux 的硬鏈接與軟鏈接

最後

爲什麼硬鏈接不能跨文件系統?
因爲當前,我的討論默認只有一個普通的文件系統。
在這裏插入圖片描述
這篇文章的缺點,沒有將操作與理論結合:
詳細內容,可以參考:理解 Linux 的硬鏈接與軟鏈接
另外,如果想更詳細的瞭解文件系統知識,可以閱讀操作系統的相關書籍。

我不維護這篇文章,即使文章中出現錯誤。
上面幫助理解的圖片,可能是錯的,我也不會修改。
能力有限,這篇文章的目的只有一個:在沒有操作系統源碼的支持情況下,理解了硬鏈接與軟連接的區別,僅此而已。


參考文章
(參考文章中的內容本人並不是都明白,特別是在VFS的地方)
Linux 文件系統剖析 --M. Jones
文件系統 --wiki
理解inode --阮一峯
inode --wiki
5分鐘讓你明白“軟鏈接”和“硬鏈接”的區別
理解 Linux 的硬鏈接與軟鏈接
多角度分析爲什麼 Linux 的硬連接不能指向目錄
文件描述符(File Descriptor)簡介
Linux文件描述符到底是什麼?
每個Unix進程都有的三個標準POSIX文件描述符

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章