為了提高linux塊裝置讀寫的效率,unix會在記憶體中建立塊快取記憶體,塊快取記憶體儲存了系統最近讀的資料塊和剛剛寫入的資料塊,也就是說io訪問其實是和塊快取記憶體打交道的(直接io除外),塊快取記憶體會適時同步髒的資料頁面(如果是同步模式則立刻同步),也就是常說的unix延遲寫,這樣會極大提高系統讀寫的效率。有人或許問,資料不直接寫在裝置上的話斷電的話資料丟失怎麼辦,只能說,對不起,沒辦法。
下面介紹三個重要的核心讀函式。
(1)__find_get_block().函式__find_get_block()的引數有:block_device描述符位址bdev,塊號block和塊大小size。函式返回頁快取記憶體中的塊緩衝區對應的緩衝區首部的位址;如果不存在指定的塊,就返回null.
(2)__getblk().__getblk()其與__find_get_block()接收相同的引數,並返回與緩衝區對應的緩衝區首部的位址。與__find_get_block()不同的是,如果塊不存在,__getblk()會分配塊裝置緩衝區頁並返回將要描述塊的緩衝區首部的指標。注意,__getblk()返回的塊緩衝區不必存有有效資料(因為還沒讀磁碟)。
struct buffer_head * __getblk(struct block_device *bdev, sector_t block, int size)
grow_buffers()這個函式就是將分配的緩衝區加入塊快取記憶體中,引數與__find_get_block相同。grow_buffers()呼叫流程如下:grow_buffers---->grow_dev_page--->find_or_create_page在塊快取記憶體中搜尋需要的頁,如果需要,就把新的頁插入快取記憶體--->add_to_page_cache_lru將塊快取加入lru鍊錶--->add_to_page_cache將塊快取加入塊快取記憶體中.
(3) __bread(). __bread()的引數也與前兩個相同,返回與緩衝區對應的緩衝區首部的位址,與__getblk()不同的是,__bread()會從讀取相應的磁碟塊,並將其填充到緩衝區。
struct buffer_head * __bread(struct block_device *bdev, sector_t block, int size)
__bread_slow()函式呼叫submit_bh()函式填充塊快取bh.
從三個函式可以看出來,它們的關係是遞進的,第乙個函式只負責在塊快取記憶體中查詢,第二個則多了乙個分配快取記憶體塊的操作,最後多了乙個從磁碟中讀取相應塊並填充快取塊的操作。
linux核心設計與實現讀書筆記 頁快取記憶體
一 頁快取記憶體 內容對應磁碟上的物理塊的記憶體物理頁面。寫快取實現策略 1 nonwrite 直接寫磁碟,同時將快取中資料失效。2 write through cache 自動更新記憶體快取同時更新磁碟檔案。3 寫回 寫到快取中並標記頁面為臟,加入髒頁鍊錶中,由寫回程序週期性寫回磁碟。linux使...
WPF中的動畫 (四)緩動函式
緩動函式可以通過一系列公式模擬一些物理效果,如實地彈跳或其行為如同在彈簧上一樣。它們一般應用在from to by動畫上,可以使得其動畫更加平滑。varwidthanimation newdoubleanimation button.beginanimation widthproperty,widt...
WPF中的動畫 (四)緩動函式
原文 wpf中的動畫 四 緩動函式 緩動函式可以通過一系列公式模擬一些物理效果,如實地彈跳或其行為如同在彈簧上一樣。它們一般應用在from to by動畫上,可以使得其動畫更加平滑。varwidthanimation newdoubleanimation button.beginanimation ...