這篇“Linux的I/O子系統(tǒng)知識(shí)點(diǎn)有哪些”文章的知識(shí)點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來(lái)看看這篇“Linux的I/O子系統(tǒng)知識(shí)點(diǎn)有哪些”文章吧。
站在用戶(hù)的角度思考問(wèn)題,與客戶(hù)深入溝通,找到久治網(wǎng)站設(shè)計(jì)與久治網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶(hù)體驗(yàn)好的作品,建站類(lèi)型包括:網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋久治地區(qū)。
read系統(tǒng)調(diào)用的處理分為用戶(hù)空間和內(nèi)核空間處理兩部分。其中,用戶(hù)空間處理只是通過(guò)0x80中斷陷入內(nèi)核,接著調(diào)用其中斷服務(wù)例程,即sys_read以進(jìn)入內(nèi)核處理流程。
對(duì)于read系統(tǒng)調(diào)用在內(nèi)核的處理,如上圖所述,經(jīng)過(guò)了VFS、具體文件系統(tǒng),如ext2、頁(yè)高速緩沖存層、通用塊層、IO調(diào)度層、設(shè)備驅(qū)動(dòng)層、和設(shè)備層。其中,VFS主要是用來(lái)屏蔽下層具體文件系統(tǒng)操作的差異,對(duì)上提供一個(gè)統(tǒng)一接口,正是因?yàn)橛辛诉@個(gè)層次,所以可以把設(shè)備抽象成文件。具體文件系統(tǒng),則定義了自己的塊大小、操作集合等。引入cache層的目的,是為了提高IO效率。它緩存了磁盤(pán)上的部分?jǐn)?shù)據(jù),當(dāng)請(qǐng)求到達(dá)時(shí),如果在cache中存在該數(shù)據(jù)且是最新的,則直接將其傳遞給用戶(hù)程序,免除了對(duì)底層磁盤(pán)的操作。通用塊層的主要工作是,接收上層發(fā)出的磁盤(pán)請(qǐng)求,并最終發(fā)出IO請(qǐng)求(BIO)。IO調(diào)度層則試圖根據(jù)設(shè)置好的調(diào)度算法對(duì)通用塊層的bio請(qǐng)求合并和排序,回調(diào)驅(qū)動(dòng)層提供的請(qǐng)求處理函數(shù),以處理具體的IO請(qǐng)求。驅(qū)動(dòng)層的驅(qū)動(dòng)程序?qū)?yīng)具體的物理設(shè)備,它從上層取出IO請(qǐng)求,并根據(jù)該IO請(qǐng)求中指定的信息,通過(guò)向具體塊設(shè)備的設(shè)備控制器發(fā)送命令的方式,來(lái)操縱設(shè)備傳輸數(shù)據(jù)。設(shè)備層都是具體的物理設(shè)備。
內(nèi)核函數(shù)sys_read是read系統(tǒng)調(diào)用在該層的入口點(diǎn)。
它根據(jù)文件fd指定的索引,從當(dāng)前進(jìn)程描述符中取出相應(yīng)的file對(duì)象,并調(diào)用vfs_read執(zhí)行文件讀取操作。
vfs_read會(huì)調(diào)用與具體文件相關(guān)的read函數(shù)執(zhí)行讀取操作,file->f_op.read。
然后,VFS將控制權(quán)交給了ext2文件系統(tǒng)。(ext2在此作為示例,進(jìn)行解析)
通過(guò)ext2_file_operations結(jié)構(gòu)知道,上述函數(shù)最終會(huì)調(diào)用到do_sync_read函數(shù),它是系統(tǒng)通用的讀取函數(shù)。所以說(shuō),do_sync_read才是ext2層的真實(shí)入口。
該層入口函數(shù) do_sync_read 調(diào)用函數(shù) generic_file_aio_read ,后者判斷本次讀請(qǐng)求的訪問(wèn)方式,如果是直接 io (filp->f_flags 被設(shè)置了 O_DIRECT 標(biāo)志,即不經(jīng)過(guò) cache)的方式,則調(diào)用 generic_file_direct_IO 函數(shù);如果是 page cache 的方式,則調(diào)用 do_generic_file_read 函數(shù)。它會(huì)判斷該頁(yè)是否在頁(yè)高速緩存,如果是,直接將數(shù)據(jù)拷貝到用戶(hù)空間。如果不在,則調(diào)用page_cache_sync_readahead函數(shù)執(zhí)行預(yù)讀(檢查是否可以預(yù)讀),它會(huì)調(diào)用mpage_readpages。如果仍然未能命中(可能不允許預(yù)讀或者其它原因),則直接跳轉(zhuǎn)readpage,執(zhí)行mpage_readpage,從磁盤(pán)讀取數(shù)據(jù)。
在mpage_readpages(一次讀多個(gè)頁(yè))中,它會(huì)將連續(xù)的磁盤(pán)塊放入同一個(gè)BIO,并延緩BIO的提交,直到出現(xiàn)不連續(xù)的塊,則直接提交BIO,再繼續(xù)處理,以構(gòu)造另外的BIO。
文件的 page cache 結(jié)構(gòu)
圖5顯示了一個(gè)文件的 page cache 結(jié)構(gòu)。文件被分割為一個(gè)個(gè)以 page 大小為單元的數(shù)據(jù)塊,這些數(shù)據(jù)塊(頁(yè))被組織成一個(gè)多叉樹(shù)(稱(chēng)為 radix 樹(shù))。樹(shù)中所有葉子節(jié)點(diǎn)為一個(gè)個(gè)頁(yè)幀結(jié)構(gòu)(struct page),表示了用于緩存該文件的每一個(gè)頁(yè)。在葉子層最左端的第一個(gè)頁(yè)保存著該文件的前4096個(gè)字節(jié)(如果頁(yè)的大小為4096字節(jié)),接下來(lái)的頁(yè)保存著文件第二個(gè)4096個(gè)字節(jié),依次類(lèi)推。樹(shù)中的所有中間節(jié)點(diǎn)為組織節(jié)點(diǎn),指示某一地址上的數(shù)據(jù)所在的頁(yè)。此樹(shù)的層次可以從0層到6層,所支持的文件大小從0字節(jié)到16 T 個(gè)字節(jié)。樹(shù)的根節(jié)點(diǎn)指針可以從和文件相關(guān)的 address_space 對(duì)象(該對(duì)象保存在和文件關(guān)聯(lián)的 inode 對(duì)象中)中取得。
mpage處理機(jī)制就是page cache層要處理的問(wèn)題。
在緩存層處理末尾,執(zhí)行mpage_submit_bio之后,會(huì)調(diào)用generic_make_request函數(shù)。這是通用塊層的入口函數(shù)。
它將bio傳送到IO調(diào)度層進(jìn)行處理。
對(duì)bio進(jìn)行合并、排序,以提高IO效率。然后,調(diào)用設(shè)備驅(qū)動(dòng)層的回調(diào)函數(shù),request_fn,轉(zhuǎn)到設(shè)備驅(qū)動(dòng)層處理。
request函數(shù)對(duì)請(qǐng)求隊(duì)列中每個(gè)bio進(jìn)行分別處理,根據(jù)bio中的信息向磁盤(pán)控制器發(fā)送命令。處理完成后,調(diào)用完成函數(shù)end_bio以通知上層完成。
以上就是關(guān)于“Linux的I/O子系統(tǒng)知識(shí)點(diǎn)有哪些”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對(duì)大家有幫助,若想了解更多相關(guān)的知識(shí)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。