linux內核開文件系統,內核必須懂(二): Linux文件系統初探

目錄

前言

文件系統結構

新建文件和inode

文件創建過程

inode解析

打開文件

參考

最后

前言

這次來說文件系統. 文件系統是非常重要的, 提高磁盤使用率, 減小磁盤磨損等等都是文件系統要解決的問題. 市面上的文件系統也是數不勝數, 比較常用的像ext4, xfs以及ntfs等等, 國內的像鵝廠的tfs, 然后還有sun號稱"last word in file system"的ZFS, 學習ZFS而來的btrfs.

下面上一張Linux文件系統組件的體系結構圖, 是我整合了多方文獻并結合自己的經驗畫出來的. 可以看出, 最重要的就是vfs, 正是因為它, 才讓Linux可以同時支持多種的文件系統. 舉個例子, 比如你裝了雙系統mint+windows, 在mint中, 你可以看到windows的ntfs磁盤, 但是返回了windows, 你就看不到mint的磁盤了.

AAffA0nNPuCLAAAAAElFTkSuQmCC

那Linux支持哪些文件系統呢? 來到源碼的fs文件夾, Linux支持的文件系統可多了去了, 注意看藍色的.

AAffA0nNPuCLAAAAAElFTkSuQmCC

文件系統結構

磁盤扇區什么的就不多說了. 也許會出一篇談存儲介質的文章, 說說ssd結構啥的. 直接跳過硬件從文件系統結構開始. 注意, 我說的是通用模型, 每個fs的具體實現有差異, 而且差異蠻大的. ext家族是Linux默認的fs了, 事實上ext2/ext3和ext4差異也很大.

superblock: 記錄此fs的整體信息, 包括inode/block的總量、使用量、剩余量, 以及文件系統的格式與相關信息等;

inode table: superblock之后就是inode table, 存儲了全部inode.

data block: inode table之后就是data block. 文件的內容保存在這個區域. 磁盤上所有塊的大小都一樣.

inode: 記錄文件的屬性, 同時記錄此文件的數據所在的block號碼. 每個inode對應一個文件/目錄的結構, 這個結構它包含了一個文件的長度、創建及修改時間、權限、所屬關系、磁盤中的位置等信息.

block: 實際記錄文件的內容. 一個較大的文件很容易分布上千個獨產的磁盤塊中, 而且, 一般都不連續, 太散會導致讀寫性能急劇下降.

好, 我猜你和我一樣是右腦思維, 上圖就好:

AAffA0nNPuCLAAAAAElFTkSuQmCC

可以看出來, 這是多層索引結構的文件系統. 用b+樹是最佳解決方案, 比如btrfs. inode table指向inode, inode指向一個或者多個block, 注意, 圖中還是直接指向, 后面還會講述多層指向. 最怕的就是inode指向的block太散. 一個比較好的解決辦法就是在文件末尾不斷添加數據, 而不是新建文件.

新建文件和inode

新建一個文件和文件夾, 用stat指令查看文件信息.

touch hello

stat hello

mkdir hellodir

stat hellodir

AAffA0nNPuCLAAAAAElFTkSuQmCC

可以看到一些信息. 例如一個目錄初始大小就是4KB, 8個block, 一個扇區就是512B, 一個io block是4KB, 對應第一幅圖的General Block Device Layer層. 這些其實不看也知道, 前提是這是常規的fs.

文件創建過程

創建成功一個文件有4步:

存儲屬性: 也就是文件屬性的存儲, 內核先找到一塊空的inode. 例如, 之前的1049143. 內核把文件的信息記錄其中. 如文件的大小、文件所有者、和創建時間等, 用stat指令都可以看到.

存儲數據: 即文件內容的存儲, 比方建立一個1B的文件, 那一個block, 8個扇區, 內核把數據放到一個空閑邏輯塊中也就是空閑block中. 很明顯, 碎片化的問題已經呈現在這里了. 1B它也要用4K對吧.

記錄分配情況: 假如數據保存到了3個block中, 位置要記錄到inode的磁盤序號列表中. 這3個編號分別放在最開始的3個位置. 然后讀的時候會一次性讀, 可以看我的第二張圖. 當然了fat就沒有inode, 它在一個塊中放了下一個塊的位置, 形成鏈, u盤就是這種fs.

添加文件名到目錄: 文件名和inode之間的對應關系將文件名和文件以及文件的內容屬性連接起來, 找到文件名就找到文件的inode,通過inode就能找到文件的屬性和內容. 換句話說, 就是機器看的和人看的做銜接, 例如網址和ip. 當然, 如果你看inode就能區分文件, 第四步可以不要(手動滑稽).

目錄的話, 就是多了點文件(指向自己), 點點文件(指向上級目錄). 然后添加自己的inode到上級目錄. 看圖就秒懂了.

AAffA0nNPuCLAAAAAElFTkSuQmCC

AAffA0nNPuCLAAAAAElFTkSuQmCC

inode解析

用df指令可以看inode的總數和使用量.

df -i

dumpe2fs打開指定磁盤可以看inode的大小, 這里是256.

AAffA0nNPuCLAAAAAElFTkSuQmCC

inode如何記錄文件并且最大是多少呢? inode記錄block號碼的區域定義為12個直接, 一個間接, 一個雙間接與一個三間接記錄區. 一個inode是4B, 這樣用4K的block可以有1K的inode.

直接: 12 * 4K

間接: (4K / 4) * 4K

雙間接: (4K / 4) * (4K / 4) * 4K

三間接: (4K / 4) * (4K / 4) * (4K / 4) * 4K

所以的話, 4T, are you OK? 算歸算, fs在不斷發展, 這是過時的大小了. ext4的話單個文件可以到達16TB, fs可達1EB. 但是注意, ext4的作者都說了, ext4只是過渡, btrfs會更棒, 那事實上, cent os用的xfs也很很棒.

打開文件

創建之后當然要打開了, 打開文件也是有一系列過程的. 先來看看兩個指令:

sysctl -a | grep fs.file-max

ulimit -n

AAffA0nNPuCLAAAAAElFTkSuQmCC

第一個指令查看os最大打開數, 這是系統級限制.

第二個指令查看單進程最大打開數, 這是用戶級限制.

進程描述符(task_struct):

為了管理進程, 操作系統要對每個進程所做的事情進行清楚地描述, 為此, 操作系統使用數據結構來代表處理不同的實體, 這個數據結構就是通常所說的進程描述符或進程控制塊(PCB). 通俗來講就是操作系統中描述進程的結構體叫做PCB.

Linux內核通過一個被稱為進程描述符的task_struct結構體來管理進程, 這個結構體包含了一個進程所需的所有信息. 它定義在include/linux/sched.h文件中. 這不是這次的重點, 但是這個task_struct結構體確實很重要, 也很復雜.

每個進程都會被分配一個task_struct結構, 它包含了這個進程的所有信息, 在任何時候操作系統都能跟蹤這個結構的信息.

文件描述符表(file_struct): 該表記錄進程打開的文件. 它的表項里面有一個指針, 指向存放在內核空間的文件表中的一個表項. 它向用戶提供一個簡單的文件描述符(fd), 使得用戶可以通過方便地訪問一個文件. 例如, 當進程使用open打開一個文件時, 內核就會在這個表中添加一個表項. 如果對同一個文件打開多次, 那么將有多個表項. 使用dup時, 也會增加一個表項.

文件表: 文件表保存了進程對文件讀寫的偏移量. 該表還保存了進程對文件的存取權限等等. 比如, 進程以O_RDONLY方式打開文件, 這將記錄到對應的文件表表項中. 然后每個表有一個指向inode table中inode的指針. 結合之前的圖片看, 所有結構就聯系起來了, 所以inode是核心點.

上圖上圖:

AAffA0nNPuCLAAAAAElFTkSuQmCC

在進程A中, 文件描述符1和2都指向了同一個打開的文件表A. 這可能是通過調用dup()、dup2()、fcntl()或者對同一個文件多次調用了open()函數而形成的.

進程A的文件描述符0和進程B的文件描述符2都指向了同一個打開的文件表A. 這種情形可能是在調用fork()后出現的(即, 進程A、B是父子進程關系), 或者當某進程通過UNIX域套接字將一個打開的文件描述符傳遞給另一個進程時, 也會發生. 再者是不同的進程獨自去調用open函數打開了同一個文件, 此時進程內部的描述符正好分配到與其他進程打開該文件的描述符一樣.

此外, 進程A的描述符0和進程B的描述符255分別指向不同的打開文件表, 但這些文件表均指向inode table的相同條目(假設), 也就是指向同一個文件. 發生這種情況是因為每個進程各自對同一個文件發起了open()調用。同一個進程兩次打開同一個文件, 也會發生類似情況.

為什么要說這些情況呢? 因為如果沒有理解清楚這些, 在做多進程多線程read和write的時候很有可能會導致讀取和寫入混亂.

參考

看了非常多很棒的文章, 這里也分享給大家.

最后

這次從結構上逐步往內解剖文件系統, inode是核心點. 當然還有兩篇甚至更多的后續文章, 最后會寫個簡單的用戶態文件系統, 喜歡記得點個贊或者關注我哦~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/528883.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/528883.shtml
英文地址,請注明出處:http://en.pswp.cn/news/528883.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

gps衛星位置計算程序matlab_科研項目 | BD/ GPS衛星導航仿真測試系統研究

一、項目背景在移動互聯和互聯網的時代,衛星導航定位已經成為生活中不可或缺的部分。目前,我國的交通、銀行、電力、采礦、測繪等部門以及大眾化市場都需要大量的定位、授時服務。許多企業也形成了覆蓋衛星導航相關材料及元器件、衛星導航芯片、衛星導航…

linux docker權限,linux - 如何解決ubuntu中的docker權限問題? - Ubuntu問答

問題描述我已經按照here的說明安裝了docker。我使用Ubuntu Trusty 14.04 (LTS) (64-bit)。安裝過程中的一切都很好。另外,命令$ sudo docker run -i -t ubuntu /bin/bash可以很好地完成(在打開的控制臺中鍵入”exit”之后。但是當我嘗試執行其他操作時,我…

python虛擬人臉生成_GitHub - 597111463/seeprettyface-generator-yellow: 這是一個用StyleGAN訓練出的黃種人人臉生成器...

黃種人人臉生成器注明:之前做的一些有意思的人臉生成器,現在全部開源分享出來。它的主要作用是可生成制作各類型的人臉素材,供我們任意使用且無須擔心人臉版權的問題。在定制人臉上,開源的全系列生成器包括:黃種人臉生…

Linux輸入密碼接口,Linux下搭建接口自動化測試平臺

前言我們今天來學習一下在Linux下如何搭建基于HttpRunner開發的接口自動化測試平臺吧!需要在Linux上提前準備的環境(下面是本人搭建時的環境):1,Python 3.6.8 (可參考隨筆:Linux學習6-安裝Python3.6)2,MySQL 5.7(可參考…

python構建字典實現英文大寫字母與ascii編碼的轉換_Python:將復雜的字符串字典從Unicode轉換為ASCII...

作為從JSON API調用解析的多級字典,我有很多輸入.字符串都是unicode,這意味著有很多ustuff like this.我正在使用jq來處理結果,需要將這些結果轉換為ASCII.我知道我可以編寫一個函數來像這樣轉換它:def convert(input):if isinstance(input, dict):ret {}for stuff in input:r…

linux下查看windows文件夾大小,如何從Windows命令行檢查文件夾的大小?

我意識到這個問題要求使用進行文件大小分析CMD line。但是,如果您愿意使用它,PowerQuery (Excel add-in, versions 2010)則可以創建一些非常引人注目的文件大小分析。下面的腳本可以粘貼到空白查詢中;您唯一需要做的就是添加一個名為“ param…

python多進程傳遞參數_急急急, Python 多進程,如何傳遞 epoll?

102019-06-16 15:39:41 08:00NoAnyLove 好的好的,我查了下,說 IPC 或向 worker 參數傳遞的東西必須要能 pickle,不然就報錯,那就是 select.epoll 是不支持的。error:TypeError: cant pickle select.epoll objects。代碼…

linux查看一小時之內的日志,linux – 在[timespan]內(例如最后一小時)查找日志文件中的條目...

我的服務器CPU使用率不高,我可以看到Apache正在使用太多的內存。我有一種感覺,我正在用一個IP進行DOS.-也許你可以幫我找到他?我已經使用以下行找到10個最“活躍”的IP:cat access.log | awk {print $1} |sort |uniq -c |sort -n …

圖像語義分割_圖像語義分割(9)-DeepLabV3: 再次思考用于圖像語義分割的空洞卷積...

論文地址 :Rethinking Atrous Convolution for Semantic Image Segmentation論文代碼:Github鏈接1. 摘要文章主要的工作:使用空洞卷積來調整濾波器的感受野并控制特征圖分辨率使用不同空洞率的空洞卷積的串聯或者并行操作來分割不同尺度的目標…

linux系統列表,Linux常用系統調用列表-20210415054405.docx-原創力文檔

LinuxLinux常用系統調用列表作者:雷震 2002年3月本文列出了大部分常見的Linux系統調用,并附有簡要中文說明。以下是Linux系統調用的一個列表,包含了大部分常用系統調用和由系統調用派 生出的的函數。按照慣例,這個列表以man pages…

sql replace 雙引號變單引號_sql-匯總、排序以及分析思路

一、匯總函數注:匯總函數,如果輸入是列名,計算會把null 排除在外,count(*)對所有的行進行計數二、如何用sql解決業務問題注1:空值(null)的排序,排序是最小的,例如select * from tea order by tea_name注2&a…

linux subversion 根目錄檢出,經驗總結:詳解Linux下Subversion的安裝配置記錄 下

上節介紹額Linux下Subversion的安裝問題,本節介紹Linux下Subversion配置問題,你可以和Windows下Subversion的安裝配置做一個對比,你就會發現在這兩種操作系統中Subversion的不同運行機制。第二章配置本系統采用為每個項目單獨建一版本庫的策略…

python用戶名密碼登錄退出_用戶登錄登出

一、功能需求分析1.登錄功能分析1.1登錄流程1.2功能(一個請求為一個功能)~登錄頁面~登錄功能~登出功能二、登錄頁面1.接口設計1.1.接口說明類目                  說明請求方式                GETurl定義…

openwrt是嵌入式linux,非常方便的OpenWrt的嵌入式Linux開發環境

今天聽中央經濟廣播電臺說,今年有559萬大學畢業生,大學生的就業形式嚴峻.我想那些精通Linux開發的畢業大學生們,估計一點也不用擔心,因為他們已經不再是一顆大白菜了.最近在幫一個朋友把OpenWrt移植到一塊單板上,有一些心得,分享給大家.OpenWrt是一個很好的學習Linux的平臺,而且…

linux添加有效群組,Linux中的有效群組和初始群組

在Linux中,每個賬號都可以加入多個群組,那用戶登錄后默認的用的是哪個群組呢?關于這個問題就要說說有效群組和初始群組了。在用戶賬號信息文件/etc/passwd中,那個由冒號分割的7個欄目中,第四個欄目是群組ID(GID)&#…

php多個表中查找數據_HeidiSQL 免費的可視化數據庫管理工具

HeidiSQL是一款免費的軟件,并且易于學習和使用。HeidiSQL讓你從數據庫內可視化的讀寫數據、結構體。它支持MariaDB、MySQL、Microsoft SQL、PostgreSQL等數據庫。功能免費且開源內置中文在同個窗口連接多個服務支持以命令行形式連接服務連接支持SSH、SSL創建修改表、…

嵌入式linux啟動根文件系統,嵌入式Linux根文件系統制作和掛載

嵌入式Linux系統由三部分組成: uboot、kernel、根文件系統, 還是這張老圖這里的根文件系統可以說是包含兩個部分: 一個是根,一個是文件系統那么什么是根呢?哈哈 其實根表示的就是第一個的意思下面貼張圖看看整個根文件…

sqlite 查詢 支持多用戶同時_SQLite支持多進程同時操作數據庫文件嗎?

多個進程可以同時打開同一個數據庫。多個進程可以同時執行SELECT。但是,只有一個進程可以隨時對數據庫進行更改。SQLite使用讀/寫鎖來控制對數據庫的訪問。(在Win95 / 98 / ME下,缺少對讀寫鎖的支持,而是使用概率模擬。)但請注意:…

python 字符串處理 字典_python 字符串和字典

一、字符串操作name "my name is \t {name} and i am {year} years old"1.首字母大寫print(name.capitalize())2.統計字符串中相同的字符print(name.count("n"))3.格式化字符串print(name.center(50,"-"))#打印50個-,把name的值放中…

查詢linux上調度命令,淺析Linux中crontab任務調度

一.創建調度任務指令crontab -e 進入當前用戶編輯界面crontab -u 用戶名 -e 進入指定用戶編輯界面進入crontab任務編輯界面任務編寫格式#每分鐘執行查看一次/ect目錄,把目錄內容寫進/tml/a.txt下*/ 1 * * * * ll /etc >> /tmp/a.text#crontab對象 指令#多個任務同時執行#…