怎樣進行Linux內(nèi)核文件系統(tǒng)的分析,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
成都創(chuàng)新互聯(lián)公司主要業(yè)務有網(wǎng)站營銷策劃、網(wǎng)站制作、成都網(wǎng)站建設、微信公眾號開發(fā)、微信小程序開發(fā)、H5頁面制作、程序開發(fā)等業(yè)務。一次合作終身朋友,是我們奉行的宗旨;我們不僅僅把客戶當客戶,還把客戶視為我們的合作伙伴,在開展業(yè)務的過程中,公司還積累了豐富的行業(yè)經(jīng)驗、全網(wǎng)整合營銷推廣資源和合作伙伴關(guān)系資源,并逐漸建立起規(guī)范的客戶服務和保障體系。
內(nèi)核存儲棧從上到下主要分為三層:1. VFS 2.Block layer 3.驅(qū)動
這張圖來自https://blog.vmsplice.net/2020/04/how-linux-vfs-block-layer-and-device.html。主要介紹了內(nèi)核中存儲棧幾個重要的數(shù)據(jù)結(jié)構(gòu)之間的連接關(guān)系。VFS層數(shù)據(jù)結(jié)構(gòu)struct block_device連接著快層數(shù)據(jù)結(jié)構(gòu)struct gendisk。塊層接收到VFS的請求發(fā)送到request_queue,驅(qū)動最后會響應該請求,操作最后的物理設備。
2.1 VFS層
VFS為不同的底層文件系統(tǒng)(ext4,XFS,NFS等)提供了一個接口層。
open,read等系統(tǒng)調(diào)用由VFS處理,然后分發(fā)給相應struct file_operations的處理函數(shù)。
塊設備使用struct block_device表示,VFS層數(shù)據(jù)結(jié)構(gòu)。struct block_device使用塊層數(shù)據(jù)結(jié)構(gòu)struct gendisk和struct request_queue連接VFS inode和struct file_operations接口。
block device nodes如/dev/sda在fs/block_dev.c中實現(xiàn),提供了橋的作用,連接VFS和Linux block layer。塊層處理實際的IO請求,并且知道磁盤的特定信息,如磁盤容量,塊大小等。
2.2 Block layer層
每一個磁盤使用數(shù)據(jù)結(jié)構(gòu)struct gendisk表示,struct hd_struct表示磁盤分區(qū)。
總是存在part0分區(qū),表示整個磁盤
IO請求隊列使用struct request_queue表示
2.3 驅(qū)動層
磁盤設備驅(qū)動程序向塊層注冊struct genhd,并設置struct request_queue以接收需要提交給物理設備的請求。
即使用戶空間可能為磁盤上的多個分區(qū)打開struct block_device實例,整個設備也只有一個struct genhd。
驅(qū)動層看不到磁盤分區(qū),因為IO請求已經(jīng)根據(jù)分區(qū)的起始位置偏移做了邏輯地址的調(diào)整處理
VFS連接著塊層struct gendisk。設備驅(qū)動連接著塊層和VFS層struct block_device。塊層和其他兩層沒有直接聯(lián)系,只是有驅(qū)動層注冊的回調(diào)函數(shù)。
內(nèi)核中的I/O流所經(jīng)過的組件如下圖所示:
這里列出一張內(nèi)核中存儲棧中主要數(shù)據(jù)結(jié)構(gòu)之間的關(guān)聯(lián)關(guān)系圖。
這里追蹤一個從用戶空間出發(fā)的read函數(shù)調(diào)用的數(shù)據(jù)流,來分析從內(nèi)核到驅(qū)動最終到物理設備硬件的過程。
3.1 內(nèi)核執(zhí)行系統(tǒng)調(diào)用sys_read響應用戶空間的read操作。
3.2 在VFS層調(diào)用vfs_read通用的文件系統(tǒng)read接口。這里會根據(jù)具體的文件系統(tǒng)類型調(diào)用相應的read函數(shù)。
3.3 這里以ext4文件系統(tǒng)為例。會執(zhí)行ext4_file_read_iter。
3.4 VFS層最主要的數(shù)據(jù)結(jié)構(gòu)式bio,它定義的一系列對文件操作的具體行為。在構(gòu)造了相應的bio數(shù)據(jù)結(jié)構(gòu)后,會調(diào)用ext4_file_read_iter將請求提交到塊層。
3.5 塊層收到請求后會根據(jù)文件系統(tǒng)是否有定義自己的submit_bio函數(shù)來調(diào)用自定義函數(shù)還是通用submit_bio。ext4文件系統(tǒng)調(diào)用的是通用submit_bio。
3.6 塊層對于VFS的請求不會直接提交到設備驅(qū)動去執(zhí)行。而是會做合并的延遲處理,因為在物理磁盤上的尋到處理是十分耗時的操作。對于可以與請求隊列中的請求進行合并的操作,會首先進行合并。否則會插入請求隊列中。內(nèi)核對于I/O調(diào)度有多種不同的算法:1.電梯調(diào)度 2. 最后期限算法 3. CFQ完全公平隊列算法 4.預期算法 5.No Operations算法。
3.7 最后會調(diào)用驅(qū)動的queue_rq方法,將請求發(fā)送給驅(qū)動程序。不同的驅(qū)動會注冊不同的queue_rq方法。這里以iscsi驅(qū)動程序為例。調(diào)用執(zhí)行scsi_queue_rq方法。
3.8 scsi_queue_rq會構(gòu)造請求cmd,然后調(diào)用scsi_dispatch_cmd,分發(fā)cmd到底層驅(qū)動。
3.9 之后根據(jù)不同的底層設備類型,調(diào)用相應的queuecommand函數(shù)執(zhí)行cmd命令。
內(nèi)核的存儲棧中,塊層起著承上啟下的作用。北向承接VFS的發(fā)送過來的IO請求,南向?qū)釉O備驅(qū)動程序,提交請求到設備驅(qū)動。這當中比較重要的幾個點是:1. 塊層對于I/O請求的合并優(yōu)化處理。這塊對于I/O的性能的影響巨大。2. 對于頁高速緩存的處理。設計到如何將磁盤數(shù)據(jù)導入到內(nèi)存,以及inode等數(shù)據(jù)結(jié)構(gòu)如何操作訪問頁數(shù)據(jù)。對于很多細節(jié)好有待分析。
看完上述內(nèi)容,你們掌握怎樣進行Linux內(nèi)核文件系統(tǒng)的分析的方法了嗎?如果還想學到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!