緩衝區頭

Linux 使用緩衝區頭來維護關於單個檔案系統塊的狀態。緩衝區頭已被棄用,新的檔案系統應該使用 iomap 代替。

函式

void brelse(struct buffer_head *bh)

釋放緩衝區。

引數

struct buffer_head *bh

要釋放的緩衝區。

描述

減少 buffer_head 的引用計數。 如果 bh 為 NULL,則此函式不執行任何操作。

如果一個 folio 上的所有緩衝區都具有零引用計數,是乾淨且未鎖定的,並且如果該 folio 是未鎖定且未處於寫回狀態,則 try_to_free_buffers() 可能會從 folio 中剝離緩衝區,以準備釋放它(有時,很少情況下,緩衝區會從 folio 中移除,但最終不會被釋放,並且緩衝區可能會稍後重新附加)。

上下文

任何上下文。

void bforget(struct buffer_head *bh)

丟棄緩衝區中的任何髒資料。

引數

struct buffer_head *bh

要忘記的緩衝區。

描述

如果寫入緩衝區的資料不再需要寫回,則呼叫此函式而不是 brelse()。 它將清除緩衝區的髒標誌,因此將跳過此緩衝區的寫回。

上下文

任何上下文。

struct buffer_head *__bread(struct block_device *bdev, sector_t block, unsigned size)

讀取一個塊。

引數

struct block_device *bdev

要讀取的塊裝置。

sector_t block

塊號,以塊大小為單位。

unsigned size

此裝置的塊大小(以位元組為單位)。

描述

讀取指定的塊,並返回引用它的緩衝區頭。記憶體從可移動區域分配,因此可以遷移。返回的緩衝區頭的引用計數已增加。呼叫者應在完成緩衝區操作後呼叫 brelse()

上下文

可能會睡眠等待 I/O。

返回值

如果塊不可讀,則返回 NULL。

struct buffer_head *get_nth_bh(struct buffer_head *bh, unsigned int count)

獲取此緩衝區之後的第 n 個緩衝區的引用。

引數

struct buffer_head *bh

開始計數的緩衝區。

unsigned int count

要跳過多少個緩衝區。

描述

這主要用於查詢 folio 中的第 n 個緩衝區; 在這種情況下,您傳遞頭部緩衝區和 folio 中的位元組偏移量除以塊大小。 它可用於其他目的,但它將在 folio 的末尾環繞,而不是返回 NULL 或繼續到下一個 folio。

返回值

請求的緩衝區,引用計數已提升。

int sync_mapping_buffers(struct address_space *mapping)

寫出並等待對映的“關聯”緩衝區

引數

struct address_space *mapping

想要寫入這些緩衝區的對映

描述

針對 mapping->i_private_list 中的緩衝區啟動 I/O,並等待該 I/O。

基本上,這是 fsync() 的一個方便函式。 mapping 是一個檔案或目錄,需要寫入這些緩衝區才能成功執行 fsync()。

int generic_buffers_fsync_noflush(struct file *file, loff_t start, loff_t end, bool datasync)

用於簡單檔案系統的通用緩衝區 fsync 實現,沒有 inode 鎖

引數

struct file *file

要同步的檔案

loff_t start

起始偏移量(以位元組為單位)

loff_t end

結束偏移量(以位元組為單位)(包含)

bool datasync

如果為 true,則僅同步必要的元資料

描述

這是 fsync 方法的通用實現,適用於在掛在 address_space 結構上的緩衝區列表中跟蹤所有非 inode 元資料的簡單檔案系統。

int generic_buffers_fsync(struct file *file, loff_t start, loff_t end, bool datasync)

用於簡單檔案系統的通用緩衝區 fsync 實現,沒有 inode 鎖

引數

struct file *file

要同步的檔案

loff_t start

起始偏移量(以位元組為單位)

loff_t end

結束偏移量(以位元組為單位)(包含)

bool datasync

如果為 true,則僅同步必要的元資料

描述

這是 fsync 方法的通用實現,適用於在掛在 address_space 結構上的緩衝區列表中跟蹤所有非 inode 元資料的簡單檔案系統。 這也確保在最後呼叫裝置快取重新整理操作。

bool block_dirty_folio(struct address_space *mapping, struct folio *folio)

將 folio 標記為髒。

引數

struct address_space *mapping

包含此 folio 的地址空間。

struct folio *folio

要標記為髒的 folio。

描述

使用 buffer_heads 的檔案系統可以使用此函式作為其 ->dirty_folio 實現。 某些檔案系統需要在呼叫此函式之前做一些工作。 不使用 buffer_heads 的檔案系統應改為呼叫 filemap_dirty_folio()

如果 folio 有緩衝區,則更新的緩衝區將設定為髒,以保持 folio 和緩衝區之間的髒狀態一致性。 新增到髒 folio 的緩衝區會被建立為髒緩衝區。

緩衝區在 folio 被標記為髒之前被標記為髒。 存在一個小的競爭視窗,其中寫回可能會看到 folio 的乾淨狀態,但看不到緩衝區的髒狀態。 這沒關係。 如果此程式碼要在緩衝區之前設定 folio 髒標誌,寫回可能會清除 folio 髒標誌,看到一堆乾淨的緩衝區,最終我們會在髒 folio 列表中得到髒緩衝區/乾淨 folio。

我們使用 i_private_lock 來鎖定 try_to_free_buffers(),同時使用 folio 的緩衝區列表。 這也防止在 folio 設定為髒後將乾淨的緩衝區新增到 folio。

上下文

只能從程序上下文中呼叫。 不會睡眠。 呼叫者必須確保在此呼叫期間無法截斷 folio,通常是透過持有 folio 鎖或在 folio 中對映一個頁面並持有頁表鎖。

返回值

如果 folio 被標記為髒,則為 True; 如果已標記為髒,則為 false。

void mark_buffer_dirty(struct buffer_head *bh)

將 buffer_head 標記為需要寫出

引數

struct buffer_head *bh

要標記為髒的 buffer_head

描述

mark_buffer_dirty() 將針對緩衝區設定髒位,然後將它的支援頁面設定為髒,然後在頁面快取中將頁面標記為髒,然後將 address_space 的 inode 附加到其超級塊的髒 inode 列表。

mark_buffer_dirty() 是原子的。 它採用 bh->b_folio->mapping->i_private_lock、i_pages 鎖和 mapping->host->i_lock。

void __brelse(struct buffer_head *bh)

釋放緩衝區。

引數

struct buffer_head *bh

要釋放的緩衝區。

描述

如果保證 bh 不為 NULL,則可以呼叫此 brelse() 的變體。

void __bforget(struct buffer_head *bh)

丟棄緩衝區中的任何髒資料。

引數

struct buffer_head *bh

要忘記的緩衝區。

描述

如果保證 bh 不為 NULL,則可以呼叫此 bforget() 的變體。

struct buffer_head *bdev_getblk(struct block_device *bdev, sector_t block, unsigned size, gfp_t gfp)

在塊裝置的緩衝區快取中獲取 buffer_head。

引數

struct block_device *bdev

塊裝置。

sector_t block

塊號。

unsigned size

bdev 的 buffer_heads 的大小。

gfp_t gfp

要使用的記憶體分配標誌。

描述

返回的緩衝區頭的引用計數已遞增,但未鎖定。 呼叫者應在完成緩衝區操作後呼叫 brelse()。 緩衝區可能不是最新的。 如果需要,呼叫者可以透過讀取它或覆蓋它來使其保持最新。

返回值

緩衝區頭,如果無法分配記憶體,則為 NULL。

struct buffer_head *__bread_gfp(struct block_device *bdev, sector_t block, unsigned size, gfp_t gfp)

讀取一個塊。

引數

struct block_device *bdev

要讀取的塊裝置。

sector_t block

塊號,以塊大小為單位。

unsigned size

此裝置的塊大小(以位元組為單位)。

gfp_t gfp

不是頁面分配標誌; 請參閱下文。

描述

您不應呼叫此函式。 您應該使用 sb_bread()、sb_bread_unmovable() 或 __bread() 之一。

讀取指定的塊,並返回引用它的緩衝區頭。 如果 gfp 為 0,則將使用塊裝置的預設 GFP 標誌分配記憶體。 如果 gfp 為 __GFP_MOVABLE,則可以從可移動區域分配記憶體。 不要傳入完整的 GFP 標誌集。

返回的緩衝區頭的引用計數已增加。 呼叫者應在完成緩衝區操作後呼叫 brelse()

上下文

可能會睡眠等待 I/O。

返回值

如果塊不可讀,則返回 NULL。

void block_invalidate_folio(struct folio *folio, size_t offset, size_t length)

使緩衝區支援的 folio 的部分或全部失效。

引數

struct folio *folio

受影響的 folio。

size_t offset

要失效的範圍的開始

size_t length

要失效的範圍的長度

描述

當 folio 的全部或部分被截斷操作失效時,將呼叫 block_invalidate_folio()

block_invalidate_folio() 不必釋放所有緩衝區,但它必須確保在 offset 之外沒有留下任何髒緩衝區,並且沒有針對截斷點之外的任何塊進行 I/O。 因為呼叫者將要釋放(並可能重用)磁碟上的那些塊。

void clean_bdev_aliases(struct block_device *bdev, sector_t block, sector_t len)

清理塊裝置中的一系列緩衝區

引數

struct block_device *bdev

要在其中清理緩衝區的塊裝置

sector_t block

要清理的塊範圍的開始

sector_t len

要清理的塊數

描述

我們正在獲取一系列塊用於資料,並且我們不希望從該函式返回開始,直到顯式將緩衝區標記為髒的時刻(希望在我們釋放該塊之前不會發生這種情況 ;-) 我們甚至不需要將其標記為非最新的 - 無論如何,沒有人可以對新分配的緩衝區有任何期望。 我們過去使用 unmap_buffer() 進行這種失效,但這是不正確的。 例如,我們絕對不想將別名標記為未對映 - 這會混淆任何可能使用 bread() 拾取它的人...

此外.. 請注意 bforget() 不會鎖定緩衝區。 因此,可能會針對最近釋放的緩衝區進行寫出 I/O。 我們不會在 bforget() 中等待該 I/O - 僅在我們真正需要時才等待 I/O 更有效。 這就是這裡發生的事情。

bool try_to_free_buffers(struct folio *folio)

釋放附加到此 folio 的緩衝區。

引數

struct folio *folio

該 folio。

描述

如果有任何緩衝區正在使用中(髒、處於寫回狀態、引用計數已提升),則不會釋放任何緩衝區。

如果 folio 是髒的,但所有緩衝區都是乾淨的,那麼我們需要確保也將 folio 標記為乾淨的。 這是因為 folio 可能是針對塊裝置的,並且稍後將緩衝區重新附加到髒 folio 將設定所有緩衝區為髒。 這會損壞同一裝置上的檔案系統資料。

這同樣適用於常規檔案系統 folio:如果所有緩衝區都是乾淨的,那麼我們將 folio 設定為乾淨並繼續。 為此,我們需要完全排除 block_dirty_folio()。 這是透過 i_private_lock 獲得的。

可以透過鎖定 folio 或持有其對映的 i_private_lock 來獲得針對 try_to_free_buffers 的排除。

上下文

程序上下文。 folio 必須被鎖定。 不會睡眠。

返回值

如果附加到此 folio 的所有緩衝區都被釋放,則為 true。

int bh_uptodate_or_lock(struct buffer_head *bh)

測試緩衝區是否是最新的

引數

struct buffer_head *bh

struct buffer_head

描述

如果緩衝區是最新的,則返回 true; 如果不是,則返回 false,並且緩衝區被鎖定。

int __bh_read(struct buffer_head *bh, blk_opf_t op_flags, bool wait)

提交已鎖定緩衝區的讀取

引數

struct buffer_head *bh

struct buffer_head

blk_opf_t op_flags

除了 REQ_OP_READ 之外,還附加 REQ_OP_* 標誌

bool wait

等待直到讀取完成

描述

成功或不等待時返回零,錯誤時返回 -EIO。

void __bh_read_batch(int nr, struct buffer_head *bhs[], blk_opf_t op_flags, bool force_lock)

提交一批未鎖定緩衝區的讀取

引數

int nr

緩衝區批次的條目數

struct buffer_head *bhs[]

一批 struct buffer_head

blk_opf_t op_flags

除了 REQ_OP_READ 之外,還附加 REQ_OP_* 標誌

bool force_lock

如果設定,則強制獲取緩衝區的鎖,否則將丟棄任何無法鎖定的緩衝區。

描述

成功或不等待時返回零,錯誤時返回 -EIO。