[Linux] Linux文件系统
🥁作者: 華丞臧.
📕????專欄:【LINUX】
各位讀者老爺如果覺得博主寫的不錯,請諸位多多支持(點贊+收藏+關注)。如果有錯誤的地方,歡迎在評論區指出。
文章目錄
- 一、Linux文件系統
- 1.1 磁盤
- 1.2 inode
- 1.3 軟硬鏈接
- 1.4 動靜態庫
一、Linux文件系統
1.1 磁盤
信息化時代就是信息產生價值的時代,信息化是當今時代發展的大趨勢,代表著先進生產力。通常我們都會將信息存放在某些硬件上,如:硬盤、內存等;當信息存放硬盤上時,信息就變成了硬盤上的文件,人們通過一些設備如電腦手機可以查看使用這些數據,我們的工作和生活,已經完全離不開視頻、音樂、圖片、文本、表格這樣的數據文件。
- 磁盤上存放著大量的文件,這些文件需要被管理組織起來,操作系統中管理和存儲文件信息的軟件機構稱為文件系統。
- 最開始存放數據的硬件是磁盤,隨著時代發展,像我們的筆記本電腦大多使用SSD硬盤,但是磁盤還是主要的存儲設備,可以用存放大量的數據,關鍵是便宜。
- 下圖是一張磁盤的結構圖,磁盤的核心就是這些盤面,盤面能夠記錄二進制序列,其原理就是通過電流產生感應磁場來改變某些特定位置的磁極從而將電信號持久化到磁盤上。
-
磁盤工作時是處于一種高速旋轉的狀態,磁頭依靠磁盤的高速旋轉引起的空氣動力效應懸浮在盤面上,磁頭在副軸馬達的帶動下可以在極短的時間內精確的切換到數據所在的磁道。
-
磁盤是一種高精度的設備,在高速旋轉的情況下,磁面上的一粒灰塵都可能會導致磁盤損壞,因此磁盤通常是在無塵的環境下密封。
-
每一個盤面都對應一個磁臂,通過這些磁臂上的磁頭來定位數據的位置,依次確定磁道(柱面)、盤面、以及扇區,這三個值稱為CHS地址。
-
扇區是硬盤的最小操作單位,但扇區對于操作系統來說還是太小了,一般操作系統有自己的硬盤操作最小單位,在linux下一般為4k。
-
為了方便管理數據,我們可以將硬盤這樣的物理塊設備,分割成多個邏輯塊設備。或者,我們也可以將多個物理塊設備,組合成一個容量更大的邏輯塊設備。
-
操作系統需要管理磁盤,將磁盤抽象為一個線性的結構,類似于卷尺拉出來是線性的收進去是圓形的,因此我們可以將磁盤想象成線性的結構數組,對磁盤的管理就可以轉換成對數組空間的管理了。
-
假設磁盤抽象的出的數組為sector disk[100000000],那么我們定位一個扇區只需要數組的下標即可(這種下標稱為LBA–邏輯塊地址),將LBA轉換成CHS地址,再將數據寫入對應的磁盤上去。
-
磁盤上存儲的基本單位是扇區(512字節常規),文件系統訪問磁盤的基本單位是4KB,即一次IO訪問8個扇區。
-
這樣做有兩個好處:一、提高IO的效率 ;二、讓軟件(OS)和硬件(磁盤)具有強相關性即解耦合。
1.2 inode
使用ll查看文件,除了文件名還可以看到文件的其他屬性,如下圖:
每行包含7列:
- 模式:代表文件的類型以及權限
- 硬鏈接數
- 文件所有者
- 所屬組
- 文件大小
- 最后修改時間
- 文件名
如果需要查看文件更詳細的信息可以使用stat命令,如下圖:
在上圖中我們可以看到文件屬性中有一個Inode字段,在Linux系統中inode用于表示唯一的一個文件。
- 不管是在Windows平臺還是在Linux系統中,我們都可以通過絕對路徑或相對路徑找到一個唯一的文件,前提是在同一目錄下都不允許重名的文件出現。
- 文件是存放在磁盤上的,不管是普通文本文件還是文件夾(Linux上通常稱為目錄)都屬于文件的一種,目錄也是文件;在這種情況下,操作系統如何在磁盤上查找到目標文件的呢 —— 給定一個一對一的映射關系。
Linux ext2文件系統,下圖為磁盤一個分區的文件系統圖(內核內存映像肯定有所不同),磁盤是典型的塊設備,硬盤分區被劃分為一個個的block。一個block的大小是由格式化的時候確定的,并且不可以更改。例如mke2fs的-b選項可以設定block大小為1024、2048或4096字節。而下圖中啟動塊(Boot Block)的大小是確定的。
- 啟動塊(Boot Block):里面包含操作系統的位置以及分區表,開機信息。
- Block Group :ext2文件系統會根據分區的大小劃分為數個Block Group。而每個Block Group都有著相同的結構組成。
- 超級塊(Super Block):存放文件系統本身的結構信息。記錄的信息主要有:bolck 和 inode的總量,未使用的block和inode的數量,一個block和inode的大小,最近一次掛載的時間,最近一次寫入數據的時間,最近一次檢驗磁盤的時間等其他文件系統的相關信息。Super Block的信息被破壞,可以說整個文件系統結構就被破壞了,因此超級快通常會備份一定數量。
- GDT(Group Descriptor Table) :塊組描述符,描述塊組屬性信息,記錄inode數、起始inode編號、block使用量以及剩余量等等信息。
- 塊位圖(Block Bitmap):Block Bitmap中記錄著Data Block中哪個數據塊已經被占用,哪個數據塊沒有被占用。
- inode位圖(inode Bitmap):每個bit表示一個inode是否空閑可用。
- i節點表(inode table):以128字節為單位,存放文件屬性 如 文件大小,所有者,最近修改時間等。
- 數據區(Data Blocks):以4KB為單位,存放文件內容。
在inode table中保存了文件對應的所有屬性,那么一個inode如何與屬于自己的文件內容關聯起來呢?
struct inode {// 文件所有屬性...blocks[15];... } //在inode的結構體中包含一個blocks的數組,這個數組保存了文件對應的block編號 //其中[0, 11]:直接保存該文件的blocks編號 //[12, 15]:指向一個datablock但是這個datablock不保存有效數據,而保存該文件所對應的其它塊編號還要注意的是,文件名也是文件屬性,但是inode里面并不保存文件名;Linux下,底層實際都是通過inode編號來標識文件。那么操作系統是如何準確幫用戶通過文件名找到對應的文件內容呢?首先,用戶對文件進行操作時都是在一個目錄下,不管是創建還是刪除。其次目錄也是一個文件,既然是文件就有屬性和內容,其屬性與普通文件類似,那么目錄文件的內容是什么呢?
文件名并沒有被保存在文件內容中,操作系統又必須通過文件名幫用戶查找文件內容,所以文件inode和文件名必須具有映射關系并且記錄下來,在Linux系統中文件名和文件inode的映射關系被保存在目錄的內容中。同時我們也注意到,Linux同一個目錄下,不可以創建多個同名文件,這說明文件名本身是一個具有Key值的東西。
- 創建一個新文件:當我們創建好一個新文件時,操作系統會找到自己所處的目錄下,根據目錄的inode編號查找到目錄的datablock,然后將文件名和inode映射關系寫入目錄的數據塊中。
- 刪除文件:操作系統刪除一個文件并不會直接清除數據,而是將標記該文件對應的屬性和數據塊的相關位圖清除(由1置0),所以刪除的文件是可以恢復的。
1.3 軟硬鏈接
- 硬鏈接:通過索引節點(inode)來鏈接。
- 軟鏈接:通過名字引用另外一個文件。
- 通過ls -l可以查看文件的硬鏈接數:
上圖可以看到軟鏈接和目標文件使用的inode編號是不同的,軟鏈接具有獨立的inode編號;并且通過軟鏈接mytest文件可以直接運行目標文件test,軟鏈接相當于一個快捷方式,類似Windows系統,其中所保存的內容是指向文件所在路徑。
//創建一個硬鏈接 ln 目標文件 硬鏈接名
硬鏈接不是獨立的文件,相當于一個指針,指向某一個inode,而硬鏈接數就是引用計數,有幾個硬鏈接指向該inode編號硬鏈接數就是幾。
軟硬鏈接的區別:軟鏈接是一個獨立的文件,有自己獨立的inode編號;硬鏈接不是一個獨立的文件,它和目標文件使用的是同一個inode。
1.4 動靜態庫
- 靜態庫:程序在編譯鏈接的時候把庫的代碼鏈接到可執行文件中,程序運行的時候將不再需要靜態庫;靜態庫Linux下后綴為.a文件,windows下后綴為.lib文件。
- 動態庫:程序在運行的時候才去鏈接動態庫的代碼,多個程序共享使用庫的代碼。動態庫Linux下后綴為.so文件,windows下后綴為.dll文件。在Linux下,程序生成默認是動態連接。
- 動態庫可以在多個程序間共享,所以動態鏈接使得可執行文件更小,節省了磁盤空間。操作系統采用虛擬內存機制允許物理內存中的一份動態庫被要用到該庫的所有進程共用,節省了內存和磁盤空間。
將生成的靜態庫刪除后,程序依舊可以正常運行,如下圖:
同樣是上面的add.c和sub.c文件形成.o文件再生成一個動態庫,將動態庫使用gcc編譯main.c文件形成可執行文件,在刪除動態庫之后,此時與靜態庫不同,該文件運行出錯表示該動態庫不存在。
那么鏈接靜態庫的時候為什么沒有這個問題呢?或者說鏈接動態庫和靜態庫兩者的區別是什么呢?
- 靜態鏈接,是將所需要的庫文件中的代碼拷貝進我們自己的代碼中,然后再形成一個可執行程序,運行時程序中已經包含了庫中的代碼不需要依賴庫。
- 與靜態鏈接不同,一個與動態庫鏈接的可執行文件僅僅包含它用到的函數入口地址的一個表,而不是外部函數所在目標文件的整個機器碼;在可執行文件開始運行以前,外部函數的機器碼由操作系統從磁盤上的該動態庫中復制到內存中,這個過程稱為動態鏈接。
我們使用的庫都是存放在磁盤上的文件,動態鏈接的可執行程序運行時會將動態鏈接庫加載到內存中,加載到內存中的庫代碼只有一份,進程通過頁表將進程地址空間和庫鏈接起來,當使用動態鏈接庫中的函數時會跳轉到庫中運行。
總結
以上是生活随笔為你收集整理的[Linux] Linux文件系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: A project
- 下一篇: Windows下Redis集群搭建