打完發現還是很混亂,所以先提供一個我覺得很棒的 youtube [影片連結](https://youtu.be/lW_V8oFxQgA?si=Asc1VMXERnb11eae),很短但把 soft link 和 hard link 的差別講得很清楚,不過也因為很短,所以一些細節的部分可能需要再自己找資料,但看完可以有一個很清晰的觀念! # Background 名詞介紹 ## link 在 UNIX 系統裡面,link 就是一個 pointer ,指向一個 file 或 subdirectory - link 的 implement 方式 $\rightarrow$ 一個 absolute 或 relative path name ## inode file control block (FCB) 在 unix 檔案系統裡的稱呼,會存關於檔案的資訊,包括 ownership, permissions, location of the file contents...等 metadata 為什麼我們需要 inode ,是因為如果我們直接把所有的 file 連續的放在 HD 上,假如說當我們要對某個中間的 file 再寫入更多的內容,就會覆蓋到原本在後面的 file。因此,為了讓我們可以把每個 file 的內容放到 disk 上分散的 blocks,我們就配給每個 file 一個 inode ,來記錄這個 file 的各個 block 在 disk 上的位置 ![inode structure](https://hackmd.io/_uploads/BkbEL6vup.png) - unix 會有一定量的 inode 被 preallocated,就算 disk 是空的,也會有一定比例的 space lost 來放 inode > $\rightarrow$ 這樣先花一點空間的做法可以提升 file system 的 performance(盡量把一個檔案的 data blocks 放離 inode block 近一點來減少 seek time > $\rightarrow$ 不過,也因為 inode 是 preallocated,我們也不希望一開始就先浪費太多空間,所以 inode 的結構會用這種多層級的方式 ![image](https://hackmd.io/_uploads/B1zILpDd6.png) 應該不用在這裡講太多,不過如果有需要,可參考更詳細的[包含 inode 的筆記](https://hackmd.io/@pipibear/Byp8DQ5d6) > 在 Allocation methods $\rightarrow$ Linked Allocation $\rightarrow$ inode ## directory 在 linux 和大部分的 OS 中,data 是存在 file 裡,而 directory 則包含了很多的 file,不管是 file 還是 directory,都是存在硬碟裡面 - 不過,directory 在 linux 中也算是「一種特殊的 file」,所以如果我們用 ``ls`` command 去把某個位置的所有東西印出來,是 directory 的 "file",最前面就會用 ``d`` 標示 > 如果是一般的 file,最前面的 ``d`` 會改成 ``-`` ![image](https://hackmd.io/_uploads/rJMJA-I5p.png) $\rightarrow$ directory 裡面會有一個簡單的 table,紀錄++檔案名稱++和對應的 ++inode 編號++,用 inode 編號去 inode list 裡找到該 inode 後,就可以再去 locate disk 上的 data blocks ![image](https://hackmd.io/_uploads/BJ1Edpv_6.png) > file system 裡的 一個 file 其實只是一個指向 inode 的 link --- # Hard Link / Soft Link Hard link 和 Soft link 是兩種 reference 硬碟上的檔案的方式,不管是哪一種都會指向檔案,差別在於它們 reference 的對象到底是什麼: - hard link refer to data 本身 - soft link 指向這個 data 的 path ## Hard (Nonsymbolic) Link hard link 等同一個存在於 HD 上的真正的 file。 舉例來說,假設有一個檔案叫做 ``File 1``, ``File 1`` 指向 HD 中實際存 ``File 1`` data 的位置,假如我們現在要建立一個 hard link 指向 ``File 1``,因為 hard link 是實際的檔案,所以它也是一個新的 file,有著跟 ``File 1`` 一樣的大小、一樣的內容我們把它稱為 ``File 2``。 如果我們 open ``File 2``,得到的會是 ``File 1`` 的內容,而且也指向和 ``File 1`` 相同的 HD 位置。 由這個例子看到,hard link 提供你兩個分開的檔案,像是 "copy" 一樣,但也不能直接把它想成 copy,因為當你對 ``File 1`` 做修改的時候, ``File 2`` 也會自動被修改,因為他們指向的是相同的 HD 位置。 除此之外,如果對 inode 本身的內容做修改, ``File 1`` 和 ``File 2`` 都會跟著改變 $\rightarrow$ 對 inode 本體 delete, rename, move ,不會影響到 hard link ![image](https://hackmd.io/_uploads/rJ4OKTv_a.png) > 圖中的 ``joan`` 是一個 directory,裡面有一些 file 名稱,還有這些 file 對應的 inode 編號,如果要去 access ``file3``,我們可以藉由它的 inode 編號 ``1421`` 去 inode list 找到對應的 inode,再透過這個 inode 裡面存的資訊,去找到這個檔案內容的位置。 ### 缺點 - 沒有辦法 link 到別的 file system 的 file - owner 就算刪除 file,但因為實際上沒有真的刪除(只是移除 link),所以仍算在這個 owner 的 disk quota 裡面 ## Soft (Symbolic) link <font color = "red">一種特殊的 file</font>,只是一個 pointer 指向不同的另一個 file (某個 file 的 path),不會指向某個 HD 上的位置,也不是一個新的 file,不會存實際的資料,++只會存 original file 的位置++ > 因為只是 pointer,所以佔用的空間少 - directory listing info 的 access permission 開頭(rwx 等資訊前面),會有一位符號,如果是 ``l``,指的就是 symbolic link <font color = "red">(非 hard link)</font> ### 優點 - 可以連到別的 file system (橫跨不同的 partition, drive) - link 可以是指向 directory ![image](https://hackmd.io/_uploads/BJaZlRP_p.png) ### 缺點 - create symbolic link 的時候不會去檢查目前的 shared files 裡面有沒有一樣的存在 ## 刪除共享的檔案 ### 問題:dangling pointers 如果有 shared file 存在 file system 中,而有某個 user 要把這個 file 刪除,我們什麼時候才能把原本 allocate 給這個 file 的空間 deallocate,重新再做使用? 如果採取的方法是一但有人刪除檔案就直接真的移除,可能會造成 **dangling pointers** ,也就是 pointer 指向根本不存在的 file (因為其他 user 的 link 還在)更糟的情況是,如果這些 dangling pointers 剛好是指向實際的 disk address,然後真的刪掉檔案後,這些位址的空間又再重新 allocate 給其他檔案使用, dangling pointers 就有可能指向別的錯的 file 的位址 #### symbolic link 的情況 這樣的問題,如果原本檔案的 sharing 是用 symbolic link 來 implement 就比較好處理。因為如果只是單純刪除 link,對 file 本身就沒有影響;如果是 file entry 本身被刪除,這個 file 原本佔用的空間就被 deallocated,雖然 links 仍會是 dangling ,但我們可以 search 這些 links 然後把他們也刪除,不過因為 search cost 太高,所以取而代之我們就把這些 link 留著,直到有要再做使用。 > Windows 就是用 symbolic link 的這種方式 #### hard link 的情況 如果是 hard link,file 裡面的 link 是指向一個原本就已經存在的 inode,在上面的例子裡,如果要刪掉 ``File 1``,其實只有 ``File 1`` 的 link 被移除,``File 2`` 仍然還是可以使用,因為 ``File 2`` 還是指向原本 HD 的同個位置 所以用 hard link implement 的一種解決 dangling pointers 的方式,就是去 maintain 一個 list,來紀錄所有對某個 file 的 reference(directory entries 或 symbolic links),當有 link 或 directory entry 的 copy 被建立時,就在 reference list 加入一個 entry,反之,如果 link 或 directory entry 被刪除,就把 reference list 上的 entry 移除。只有當 reference list 是空的的時候才真的把檔案刪除。 用這個方法會產生的問題就是,要 maintain 的 reference list 太大了,所以取而代之,我們紀錄 reference count 即可,每當 link 或 directory entry 的 copy 被建立,將增加 reference count ,被刪除就減少 reference count,直到 reference count 是 0 時就可以真的把檔案刪除。 > UNIX 的 hard link 就是用這種方法 --- # Reference - [Linux File System](https://users.soict.hust.edu.vn/linhtd/courses/CompLit_EN/part01-linux/02-FileSystem.pdf) - [Linux Hard Links versus Soft Links Explained](https://www.cbtnuggets.com/blog/certifications/open-source/linux-hard-links-versus-soft-links-explained) - 恐龍 p.548-549