目錄
前言:
簡單理解文件系統
細節理解
前言:
前文我們介紹了磁盤,介紹磁盤的原因是因為我們需要在理解文件系統之前,通過磁盤的了解,介紹一些文件相關的內容,比如文件是如何在磁盤里面存儲的,什么是CHS定址法,為什么OS不使用CHS定址法,什么是LBA塊等。
我們今天的介紹順序是,先簡單搭建起來對文件系統的理解,再深挖細節問題。
那么,進入今日的話題吧!
簡單理解文件系統
對于文件系統框架的搭建,我們可以先從這個指令進入:
即stat指令,查看文件的信息,這個信息,是文件的屬性?還是文件的內容呢?
我們知道文件 = 屬性 + 內容,但是我們常常關注的都是文件的內容,對于文件的屬性我們關注的并沒有那么常見。所以要理解文件系統的框架,我們要從文件的屬性進入。
由stat提供的信息來看,我們看到了File:main.c,這個代表的是文件名,Size代表的是文件的大小,Blocks?IO Block? Inode?這些都是什么?
不急,我們再次引入上文的話題:
對于上文,將磁盤從非線性的轉換為了線性的,然后線性的空間我們看成了數組,那么數組,我們可以通過位圖的類似做法,找到數據的存儲地址。但是因為磁盤取數據的特殊點,取數據都是一次性的取4kb數據,所以OS為了方便將數據分為了多個塊,也就是LBA塊,分好之后,找到一整塊空間就十分容易了。
所以我們對于文件的管理從磁盤,到了CHS,到了數組,到了LBA,最后無非就是搞清楚LBA里面究竟有什么就可以了:
形象的圖片就是這樣,那么塊組里面,我們分清楚了有Super Block, Group Deseciptor Table, Block Bitmap, Inode Table, Data Blocks。
那么我們從哪里開始討論呢?
從Data Blocks開始討論:Data Blocks是數據塊的翻譯,也就是文件的內容都是放在這里的,但是因為方便介紹,我們將Data Blocks的大小縮小成了和其他差不多的大小。對于該塊,占據的空間大小應該是整個塊組的95%以上。
那么對于Data Blocks里面都有什么呢?
看起來是非常抽象的,因為Data Blocks里面存儲的都是一個一個的數據塊,大小都是為4kb的,取的時候就直接將該數據塊丟出去就行了。
對于這么多的數據塊,都是只存儲文件的內容的。?
并且,我們知道,文件 = 內容 + 屬性,對于文件內容屬性而言,Linux特定的文件系統是將文件的屬性和內容分開存儲的,這點我們先記住。對于Data Blocks我們就探討到這里。
那么下一個,就是Block?Bitmap,相信在C++學習的時候,同學們都是知道位圖這個概念的。
最開始介紹位圖的時候,都是通過的判斷數據是否在一堆數據的集合里面,這里同理,引入block Bitmap就是為了判斷是否某個數據塊是否存在數據,這里位圖就不多介紹了,但是引入了位圖,確實能在遍歷數據塊上節省極大部分的時間。
下一個就是非常重要的inode Table,inode Table成為i節點表,存放的是文件的屬性,文件的大小,所有者,最近的修改時間等。這是inode Table。
那么文件的屬性一般都有什么呢?
struct inode
{int size;mode_t mode;int creater;int time;...int inode_number;int datablocks[N];
};
我們拿幾個非常常見的出來舉例,文件大小,文件的權限,創建時間等,但是最重要的,我們應該關心inode_number和datablocks[N]。而這個塊的名字是inode_table,所以它所處的空間自然是這么多個結構體所處的集合。
所以!!文件的屬性不過是一個一個完全相同的結構體!!
而在里面,inode的結構體如何分區的呢,都是通過inode_number進行分區的,那么datablocks的作用是什么呢?我們使用文件的時候,通過了inode_number找到了對應的文件屬性結構體,我們需要找到內容,就需要datablocks,這個數據指向的內容就是block Data的空間:
像這樣,比如N等于12的時候,前11個直接指向的數據塊,但是我們沒有辦法找到對應的大文件,所以第12個,指向的Data Blocks里面也存放的指針,指向了其他的數據塊,就有一種指數的感覺。
那么數據還不夠,13 14后面都可以指向,并且就不是一層關系這么簡單了,是一層指向一層,一層又指向一層,套好幾層最后才指向數據,這樣就能找到大文件的數據了。
這種查找數據的方法叫做ext2文件系統,我們目前大多數使用的都是ext2,還有ext3 ext4等。
所以對于inode結構體我們就知道了個所以然,那么inode bitmap?那不就是同理了嗎!!
通過inode bitmap找到表里面的某個位置是否存在文件的屬性,然后進行后續的操作。
那么現在,我們就清楚了inode table, inode bitmap, data blocks, data bitmap。對于剩下的兩個,比如GDT,也就是Group Descriptor table,翻譯過來叫做塊組描述符,描述的是塊組的屬性信息,其實就是這個塊的信息了,這更加體現了一種分治的思想。
對于Super blocks,它的名字可就厲害了,叫做超級塊,存放的是文件系統本身的結構信息,而且不是每個組都有的,可能幾個組才回有一個。比如存放的有inode使用的個數,未使用的個數,datablocks的使用個數,datablocks未使用的個數。這些都是超級塊所要記錄的內容。
那么提問,既然是記錄所有的結構信息,為什么要整這么多個呢?
因為磁盤是可能損壞的,如果損壞的時候,剛好磁頭給一個超級塊的內容消除了,那么這不就完蛋了嗎??所有多存儲幾個,增加了容錯率!!
說了那么多,inode是十分重要的,查看inode是-i:
細節理解
對于上文來說,我們已經理解了塊里面的6個成員,現在我們來談論具體細節問題:
第一個細節:
如何通過inode找到對應的data blocks??
因為inode和data都是以分區為單位的,所以inode可以通過數組datablocks找到的!
第二個細節:
我們使用的不是一直都是文件名嗎?好像并沒有使用inode,可是我們改變文件內容的時候,一直使用的都是文件名啊?
這個時候,我們就要談談目錄了,目錄 = 文件屬性 + 文件內容,這里可不要認為目錄就不是文件了,提問,目錄的文件內容是什么呢?
目錄的文件內容 = 文件名和inode的編號關系,當我們創建好了一個文件,文件所在的目錄就會記錄該文件和inode的關系,方便找到并進行修改。
所以目錄里面的文件名就是和inode映射關系!!
到了這里,相信同學們能理解為什么一個目錄下不能創建多個同名文件了吧?因為如果創建了同名文件,映射關系一亂,整個文件系統就癱瘓了。
可是!!當我們修改目錄的時候,用的還是目錄名啊!!又是什么存儲的目錄和inode的關系呢?
看這個:
pwd打印出來了路徑,是因為環境變量PATH,而我們在該目錄下修改文件,需要找到對應的inode,找到inode之前,我們需要找到該文件所在的目錄,找到該文件所在的目錄,我們就應該要找到目錄的目錄,最后直接到了根目錄!!
而在根目錄這里,就是OS已經提前加載好了有關路徑緩存的信息了,這里涉及到了知識點有結構體dentry,格式化,掛載等。我們先不管,我們只需要知道,Linux會緩存路徑信息,從而我們可以通過文件 目錄來修改對應內容。
現在,我們順便回顧一下目錄的r w,當我們將r去掉之后,也就是沒有可讀權限:
此時目錄就不允許我們讀取文件內容,本質就是不讓我們知道文件名和inode的映射關系。
這里就不演示了,當我們沒有了w權限之后,我們無法創建文件,本質就是因為不要我們創建文件名和Inode的映射關系!!
所以,對于細節2,我們可以得出結論:
1 目錄下不能創建同名文件,因為會打亂映射關系
2 查找的文件順序是通過文件名查找對應的inode編號
3 r是讓我們找到對應的映射關系,w是不讓我們寫入對應的映射關系
第三個細節:
我們如何理解文件的增刪查改呢?
文件增,就是找到對應的映射關系,在datablock里面增加數據,查就是找對應的映射關系,改也是通過inode,修改datablocks里面的數據關系。
那么刪除呢?
其實這里的刪除是一種偽刪除。
即將Inode bitmap , datablock bitmap都置為0即可。這是一種刪除。
我們對于文件系統的框架有了簡單的理解,那么理解接下來的軟硬連接動態庫就會輕松很多了。
感謝閱讀!