Linux文件系統(tǒng)基本概念記錄

真是一個無情的搬運工

前言

本文同樣更新在私人公眾號上吨些,在此推廣一下歡迎大家關(guān)注:

公眾號會定期更新一些計算機系統(tǒng)的底層知識,爭取以最細節(jié)刁愿、最簡潔的方式幫助讀者理解系統(tǒng)的一些知識绰寞。

image.png

inode

文件儲存在硬盤上,硬盤的最小存儲單位叫做"扇區(qū)"(Sector)铣口。每個扇區(qū)儲存512字節(jié)(相當于0.5KB)滤钱。

操作系統(tǒng)讀取硬盤的時候,不會一個個扇區(qū)地讀取脑题,這樣效率太低件缸,而是一次性連續(xù)讀取多個扇區(qū),即一次性讀取一個"塊"(block)叔遂。這種由多個扇區(qū)組成的"塊"他炊,是文件存取的最小單位。"塊"的大小已艰,最常見的是4KB痊末,即連續(xù)八個 sector組成一個 block。

  • inode內(nèi)容

inode包含文件的元信息哩掺,具體來說有以下內(nèi)容:

* 文件的字節(jié)數(shù)

* 文件擁有者的User ID

* 文件的Group ID

* 文件的讀凿叠、寫、執(zhí)行權(quán)限

* 文件的時間戳,共有三個:ctime指inode上一次變動的時間盒件,mtime指文件內(nèi)容上一次變動的時間蹬碧,atime指文件上一次打開的時間。

* 鏈接數(shù)履恩,即有多少文件名指向這個inode

* 文件數(shù)據(jù)block的位置

  • inode大小

inode也會消耗硬盤空間锰茉,所以硬盤格式化的時候呢蔫,操作系統(tǒng)自動將硬盤分成兩個區(qū)域切心。一個是數(shù)據(jù)區(qū),存放文件數(shù)據(jù)片吊;另一個是inode區(qū)(inode table)绽昏,存放inode所包含的信息。

每個inode節(jié)點的大小俏脊,一般是128字節(jié)或256字節(jié)全谤。inode節(jié)點的總數(shù),在格式化時就給定爷贫,一般是每1KB或每2KB就設(shè)置一個inode认然。假定在一塊1GB的硬盤中,每個inode節(jié)點的大小為128字節(jié)漫萄,每1KB就設(shè)置一個inode卷员,那么inode table的大小就會達到128MB,占整塊硬盤的12.8%腾务。

讀取文件的過程

  • 首先毕骡,系統(tǒng)找到這個文件名對應(yīng)的inode號碼;
  • 其次岩瘦,通過inode號碼未巫,獲取inode信息;
  • 最后启昧,根據(jù)inode信息叙凡,找到文件數(shù)據(jù)所在的block,讀出數(shù)據(jù)密末。

硬鏈接

一般情況下狭姨,文件名和inode號碼是"一一對應(yīng)"關(guān)系,每個inode號碼對應(yīng)一個文件名苏遥。但是饼拍,Unix/Linux系統(tǒng)允許,多個文件名指向同一個inode號碼田炭。

這意味著师抄,可以用不同的文件名訪問同樣的內(nèi)容;對文件內(nèi)容進行修改教硫,會影響到所有文件名叨吮;但是辆布,刪除一個文件名,不影響另一個文件名的訪問茶鉴。這種情況就被稱為"硬鏈接"(hard link)锋玲。

ln命令可以創(chuàng)建硬鏈接: ln 源文件 目標文件

軟鏈接

文件A和文件B的inode號碼雖然不一樣,但是文件A的內(nèi)容是文件B的路徑涵叮。讀取文件A時惭蹂,系統(tǒng)會自動將訪問者導(dǎo)向文件B。因此割粮,無論打開哪一個文件盾碗,最終讀取的都是文件B。這時舀瓢,文件A就稱為文件B的"軟鏈接"(soft link)或者"符號鏈接(symbolic link)廷雅。

這意味著,文件A依賴于文件B而存在京髓,如果刪除了文件B航缀,打開文件A就會報錯:"No such file or directory"。這是軟鏈接與硬鏈接最大的不同:文件A指向文件B的文件名堰怨,而不是文件B的inode號碼芥玉,文件B的inode"鏈接數(shù)"不會因此發(fā)生變化。

一個數(shù)據(jù)塊大小4KB诚些,則一個位圖塊可以表示410248個數(shù)據(jù)塊的使用情況飞傀,所以一個塊組中可存儲數(shù)據(jù)的大小是128MB(4 * 1024 * 8 * 4KB)

EXT-x文件系統(tǒng)中數(shù)據(jù)塊映射

Ext2/Ext3中數(shù)據(jù)塊映射方式:


image.png
image.png

于是inode
1024+ 1024^2 +1024^3+12=1,074,791,436

Extent學(xué)習(xí)記錄

Ext4中用extent樹代替了邏輯塊映射。使用extents诬烹,用一個struct ext4_extent結(jié)構(gòu)就可以映射多個數(shù)據(jù)塊砸烦,減少元數(shù)據(jù)塊的使用。

extent結(jié)構(gòu)是12個字節(jié)绞吁,所以你可以在每個inode中最多試用5個extent幢痘。然后,前12個字節(jié)是extent區(qū)(40到51字節(jié))家破,被一個extent頭結(jié)構(gòu)占用颜说,所以一個inode中實際上可以包含4個extent。

每個extent結(jié)構(gòu)中只有16個bit用來保存塊號汰聋,實際上门粪,最高位被保存了下來(最高位用來表示這個externt是“保存?預(yù)分烹困?”還是已經(jīng)初始化玄妈, 部分用于EXT4的預(yù)分配功能)。這意味著,一個extent最大只能包含2的15次方個塊拟蜻,當一個block為4k大小的時候绎签,即128MB。

128MB看起來足夠大了酝锅,但是當你的文件大于0.5G的時候诡必,這個文件就需要大于4個extent來保存整個block的索引∩Ρ猓或者爸舒,當你的文件很小,但是由很多不連續(xù)的片段組成阁谆。這些情況下碳抄,就需要用大于4個extent來組織文件愉老。

Extent并沒有非常詳細的了解场绿,后期有需要補充

Ext4中目錄項

Ext4文件系統(tǒng)中,一個目錄差不多是一個平面文件嫉入,映射任意長度的字符串到文件系統(tǒng)中的一個inode焰盗。文件系統(tǒng)中存在多個目錄項引用同一個inode——硬鏈接,這也是硬鏈接不能鏈接其他文件系統(tǒng)中的文件的原因咒林。

在目錄中并沒有存儲文件的數(shù)據(jù)信息熬拒,而只是存儲了一個類似C語言指針的東東,這個東東就是文件的inode id垫竞。而目錄中的子目錄數(shù)據(jù)和文件數(shù)據(jù)仍然是平鋪在磁盤上的澎粟。這樣,在目錄中通過這個指針就可以輕易的找到文件的數(shù)據(jù)欢瞪,而且目錄的數(shù)據(jù)和文件的數(shù)據(jù)組織也變得非常簡單活烙。

image.png

目錄本質(zhì)上也是一個文件,只不過其中存儲的數(shù)據(jù)是關(guān)于子目錄和文件的名稱信息

那么這個大數(shù)組中的元素是什么呢遣鼓?就是圖6所示的這個結(jié)構(gòu)體啸盏。從該結(jié)構(gòu)體可以看出,每一項內(nèi)容包括inode的id骑祟、該結(jié)構(gòu)體的大小回懦、文件(子目錄)名大小和文件名等信息。在檢索目錄內(nèi)容的時候次企,其實就是根據(jù)文件名獲得inode的id怯晕,然后在根據(jù)該id從inode表中獲得inode(文件)的詳細信息。

image.png

目錄查詢加速

在Ext4文件系統(tǒng)中這個索引是通過一個成為哈希樹(多叉樹)的方式實現(xiàn)的缸棵,其中Key為文件名的哈希值舟茶,而Value則是具體的數(shù)據(jù)位置(磁盤塊位置)。由于Key是有序的,因此查找非常方便稚晚,也就是可以通過文件名快速的找到ext4_dir_entry_2崇堵,然后可以找到inode信息。

image.png
image.png

超級塊

在Linux操作系統(tǒng)的文件系統(tǒng)中客燕,超級塊相當于文件系統(tǒng)的地圖鸳劳。在超級塊中保存著文件系統(tǒng)的屬性信息余素、磁盤布局和資源使用情況等信息垦写。文件系統(tǒng)通過超級塊了解磁盤的布局谢翎,查找已用和可用資源等赤屋。超級塊又相當于入口伶授,文件系統(tǒng)的操作通常從超級塊開始

struct super_block {  
746         struct list_head        s_list;         /* Keep this first */  
747         kdev_t                  s_dev;  
748         unsigned long           s_blocksize;  
749         unsigned char           s_blocksize_bits;  
750         unsigned char           s_dirt;  
751         unsigned long long      s_maxbytes;     /* Max file size */  
752         struct file_system_type *s_type;  
753         struct super_operations *s_op;  
754         struct dquot_operations *dq_op;  
755         struct quotactl_ops     *s_qcop;  
756         unsigned long           s_flags;  
757         unsigned long           s_magic;  
758         struct dentry           *s_root;  
759         struct rw_semaphore     s_umount;  
760         struct semaphore        s_lock;  
761         int                     s_count;  
762         atomic_t                s_active;  
763   
764         struct list_head        s_dirty;        /* dirty inodes */  
765         struct list_head        s_locked_inodes;/* inodes being synced */  
766         struct list_head        s_files;  
767   
768         struct block_device     *s_bdev;  
769         struct list_head        s_instances;  
770         struct quota_info       s_dquot;        /* Diskquota specific options */  
771   
772         union {  
773                 struct minix_sb_info    minix_sb;  
774                 struct ext2_sb_info     ext2_sb;  
775                 struct ext3_sb_info     ext3_sb;  
776                 struct hpfs_sb_info     hpfs_sb;  
777                 struct ntfs_sb_info     ntfs_sb;  
778                 struct msdos_sb_info    msdos_sb;  
779                 struct isofs_sb_info    isofs_sb;  
780                 struct nfs_sb_info      nfs_sb;  
781                 struct sysv_sb_info     sysv_sb;  
782                 struct affs_sb_info     affs_sb;  
783                 struct ufs_sb_info      ufs_sb;  
784                 struct efs_sb_info      efs_sb;  
785                 struct shmem_sb_info    shmem_sb;  
786                 struct romfs_sb_info    romfs_sb;  
787                 struct smb_sb_info      smbfs_sb;  
788                 struct hfs_sb_info      hfs_sb;  
789                 struct adfs_sb_info     adfs_sb;  
790                 struct qnx4_sb_info     qnx4_sb;  
791                 struct reiserfs_sb_info reiserfs_sb;  
792                 struct bfs_sb_info      bfs_sb;  
793                 struct udf_sb_info      udf_sb;  
794                 struct ncp_sb_info      ncpfs_sb;  
795                 struct usbdev_sb_info   usbdevfs_sb;  
796                 struct jffs2_sb_info    jffs2_sb;  
797                 struct cramfs_sb_info   cramfs_sb;  
798                 void                    *generic_sbp;  
799         } u;  
800         /* 
801          * The next field is for VFS *only*. No filesystems have any business 
802          * even looking at it. You had been warned. 
803          */  
804         struct semaphore s_vfs_rename_sem;      /* Kludge */  
805   
806         /* The next field is used by knfsd when converting a (inode number based) 
807          * file handle into a dentry. As it builds a path in the dcache tree from 
808          * the bottom up, there may for a time be a subpath of dentrys which is not 
809          * connected to the main tree.  This semaphore ensure that there is only ever 
810          * one such free path per filesystem.  Note that unconnected files (or other 
811          * non-directories) are allowed, but not unconnected diretories. 
812          */  
813         struct semaphore s_nfsd_free_path_sem;  
814 }

s_list:指向超級塊鏈表的指針涮因,這個struct list_head是很熟悉的結(jié)構(gòu)了拒迅,里面其實就是用于連接關(guān)系的prev和next字段沥寥。

內(nèi)核中的結(jié)構(gòu)處理都是有講究的(內(nèi)核協(xié)議棧中也說過)颤练,內(nèi)核單獨使用一個簡單的結(jié)構(gòu)體將所有的super_block都鏈接起來既忆,但是這個結(jié)構(gòu)不是super_block本身,因為本身數(shù)據(jù)結(jié)構(gòu)太大嗦玖,效率不高患雇,所有僅僅使用

struct

{

list_head prev;

list_head next;

}

這樣的結(jié)構(gòu)來將super_block中的s_list鏈接起來,那么遍歷到s_list之后宇挫,直接讀取super_block這么長的一個內(nèi)存塊苛吱,就可以將這個

super_block直接讀進來!這樣就很快捷方便器瘪!這也是為什么s_list必須放在第一個字段的原因翠储。

s_dev:包含該具體文件系統(tǒng)的塊設(shè)備標識符。例如橡疼,對于 /dev/hda1援所,其設(shè)備標識符為 0x301

s_blocksize:文件系統(tǒng)中數(shù)據(jù)塊大小,以字節(jié)單位

s_blocksize_bits:上面的size大小占用位數(shù)衰齐,例如512字節(jié)就是9 bits

s_dirt:臟位任斋,標識是否超級塊被修改

s_maxbytes:允許的最大的文件大小(字節(jié)數(shù))

struct file_system_type *s_type:文件系統(tǒng)類型(也就是當前這個文件系統(tǒng)屬于哪個類型?ext2還是fat32)

要區(qū)分“文件系統(tǒng)”和“文件系統(tǒng)類型”不一樣耻涛!一個文件系統(tǒng)類型下可以包括很多文件系統(tǒng)即很多的super_block废酷,后面會說!

struct super_operations *s_op:指向某個特定的具體文件系統(tǒng)的用于超級塊操作的函數(shù)集合

struct dquot_operations *dq_op:指向某個特定的具體文件系統(tǒng)用于限額操作的函數(shù)集合

struct quotactl_ops *s_qcop:用于配置磁盤限額的的方法抹缕,處理來自用戶空間的請求
s_flags:安裝標識

s_magic:區(qū)別于其他文件系統(tǒng)的標識

s_root:指向該具體文件系統(tǒng)安裝目錄的目錄項

s_umount:對超級塊讀寫時進行同步

s_lock:鎖標志位澈蟆,若置該位,則其它進程不能對該超級塊操作

s_count:對超級塊的使用計數(shù)

s_active:引用計數(shù)

s_dirty:已修改的索引節(jié)點inode形成的鏈表卓研,一個文件系統(tǒng)中有很多的inode趴俘,有些inode節(jié)點的內(nèi)容會被修改睹簇,那么會先被記錄,然后寫回磁盤寥闪。

s_locked_inodes:要進行同步的索引節(jié)點形成的鏈表

s_files:所有的已經(jīng)打開文件的鏈表太惠,這個file和實實在在的進程相關(guān)的

s_bdev:指向文件系統(tǒng)被安裝的塊設(shè)備

u:u 聯(lián)合體域包括屬于具體文件系統(tǒng)的超級塊信息

s_instances:具體的意義后來會說的!(同一類型的文件系統(tǒng)通過這個子墩將所有的super_block連接起來)

s_dquot:磁盤限額相關(guān)選項

文件系統(tǒng)中的各個數(shù)據(jù)結(jié)構(gòu)源碼:
https://www.cnblogs.com/linux-xin/p/8126999.html

參考鏈接

http://www.ruanyifeng.com/blog/2011/12/inode.html

https://www.cnblogs.com/alantu2018/p/8461272.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疲憋,一起剝皮案震驚了整個濱河市凿渊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌缚柳,老刑警劉巖埃脏,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異秋忙,居然都是意外死亡彩掐,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門灰追,熙熙樓的掌柜王于貴愁眉苦臉地迎上來堵幽,“玉大人,你說我怎么就攤上這事监嗜⌒程矗” “怎么了抡谐?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵裁奇,是天一觀的道長。 經(jīng)常有香客問我麦撵,道長刽肠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任免胃,我火速辦了婚禮音五,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘羔沙。我一直安慰自己躺涝,他們只是感情好,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布扼雏。 她就那樣靜靜地躺著坚嗜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诗充。 梳的紋絲不亂的頭發(fā)上苍蔬,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天,我揣著相機與錄音蝴蜓,去河邊找鬼碟绑。 笑死俺猿,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的格仲。 我是一名探鬼主播押袍,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼凯肋!你這毒婦竟也來了伯病?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤否过,失蹤者是張志新(化名)和其女友劉穎午笛,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苗桂,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡药磺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了煤伟。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片癌佩。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖便锨,靈堂內(nèi)的尸體忽然破棺而出围辙,到底是詐尸還是另有隱情,我是刑警寧澤放案,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布姚建,位于F島的核電站,受9級特大地震影響吱殉,放射性物質(zhì)發(fā)生泄漏掸冤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一友雳、第九天 我趴在偏房一處隱蔽的房頂上張望稿湿。 院中可真熱鬧,春花似錦押赊、人聲如沸饺藤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涕俗。三九已至,卻和暖如春崇棠,著一層夾襖步出監(jiān)牢的瞬間咽袜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工枕稀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留询刹,地道東北人谜嫉。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像凹联,于是被迫代替她去往敵國和親沐兰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容