快取後端 API

FS-Cache 系統提供了一個 API,實際的快取可以透過該 API 提供給 FS-Cache,然後由 FS-Cache 提供給網路檔案系統和其他感興趣的各方。 此 API 被以下系統使用

#include <linux/fscache-cache.h>.

概述

與 API 的互動在三個級別上處理:快取、卷和資料儲存,每個級別都有自己的 cookie 物件型別

COOKIE

C 型別

快取 cookie

struct fscache_cache

卷 cookie

struct fscache_volume

資料儲存 cookie

struct fscache_cookie

Cookie 用於向快取提供一些檔案系統資料,管理狀態並在訪問期間固定快取,此外還可以作為 API 函式的參考點。 每個 cookie 都有一個除錯 ID,該 ID 包含在跟蹤點中,以便更容易關聯跟蹤。 但是請注意,除錯 ID 只是從遞增的計數器中分配的,最終會迴繞。

快取後端和網路檔案系統都可以請求快取 cookie - 如果它們請求具有相同名稱的 cookie,它們將獲得相同的 cookie。 但是,卷 cookie 和資料 cookie 僅應檔案系統的請求而建立。

快取 Cookie

快取在 API 中由快取 cookie 表示。 這些是型別的物件

struct fscache_cache {
        void            *cache_priv;
        unsigned int    debug_id;
        char            *name;
        ...
};

快取後端可能對一些欄位感興趣。 debug_id 可以在跟蹤中用於匹配引用同一快取的行,name 是註冊快取時使用的名稱。 cache_priv 成員是快取上線時提供的私有資料。 其他欄位供內部使用。

註冊快取

當快取後端想要使快取上線時,它應該首先註冊快取名稱,這將使其獲得快取 cookie。 這是透過以下方式完成的

struct fscache_cache *fscache_acquire_cache(const char *name);

這將查詢並可能建立一個快取 cookie。 快取 cookie 可能已被尋找它的網路檔案系統建立,在這種情況下,將使用該快取 cookie。 如果快取 cookie 未被另一個快取使用,它將被移動到準備狀態,否則它將返回繁忙。

如果成功,快取後端可以開始設定快取。 如果初始化失敗,快取後端應呼叫

void fscache_relinquish_cache(struct fscache_cache *cache);

重置並丟棄 cookie。

使快取上線

設定好快取後,可以透過呼叫以下命令使其上線

int fscache_add_cache(struct fscache_cache *cache,
                      const struct fscache_cache_ops *ops,
                      void *cache_priv);

這會將快取操作表指標和快取私有資料儲存到快取 cookie 中,並將快取移動到活動狀態,從而允許進行訪問。

從服務中撤回快取

快取後端可以透過呼叫此函式從服務中撤回快取

void fscache_withdraw_cache(struct fscache_cache *cache);

這會將快取移動到撤回狀態,以防止新的快取級和卷級訪問開始,然後等待未完成的快取級訪問完成。

然後,快取必須遍歷其擁有的資料儲存物件,並告知 fscache 撤回它們,呼叫

void fscache_withdraw_cookie(struct fscache_cookie *cookie);

在每個物件所屬的 cookie 上。 這會安排指定的 cookie 進行撤回。 這將被解除安裝到工作佇列。 快取後端可以透過呼叫以下命令等待完成

void fscache_wait_for_objects(struct fscache_cache *cache);

一旦所有 cookie 都被撤回,快取後端可以撤回所有卷,呼叫

void fscache_withdraw_volume(struct fscache_volume *volume);

告知 fscache 卷已被撤回。 這將等待捲上的所有未完成訪問完成後再返回。

當快取完全撤回後,應透過呼叫以下命令通知 fscache

void fscache_relinquish_cache(struct fscache_cache *cache);

清除 cookie 中的欄位並丟棄呼叫者的引用。

卷 Cookie

在快取中,資料儲存物件被組織成邏輯卷。 這些在 API 中表示為型別的物件

struct fscache_volume {
        struct fscache_cache            *cache;
        void                            *cache_priv;
        unsigned int                    debug_id;
        char                            *key;
        unsigned int                    key_hash;
        ...
        u8                              coherency_len;
        u8                              coherency[];
};

這裡有許多欄位是快取後端感興趣的

  • cache - 父快取 cookie。

  • cache_priv - 快取存放私有資料的地方。

  • debug_id - 用於在跟蹤點中記錄的除錯 ID。

  • key - 一個可列印的字串,其中沒有“/”字元,表示卷的索引鍵。 鍵以 NUL 結尾並填充到 4 位元組的倍數。

  • key_hash - 索引鍵的雜湊值。 無論 cpu 架構和位元組序如何,這都應該相同。

  • coherency - 一段一致性資料,應在卷繫結到快取中時進行檢查。

  • coherency_len - 一致性緩衝區中的資料量。

資料儲存 Cookie

卷是資料儲存物件的邏輯組,每個物件由 cookie 向網路檔案系統表示。 Cookie 在 API 中表示為型別的物件

struct fscache_cookie {
        struct fscache_volume           *volume;
        void                            *cache_priv;
        unsigned long                   flags;
        unsigned int                    debug_id;
        unsigned int                    inval_counter;
        loff_t                          object_size;
        u8                              advice;
        u32                             key_hash;
        u8                              key_len;
        u8                              aux_len;
        ...
};

cookie 中快取後端感興趣的欄位是

  • volume - 父卷 cookie。

  • cache_priv - 快取存放私有資料的地方。

  • flags - 一組位標誌,包括

    • FSCACHE_COOKIE_NO_DATA_TO_READ - 快取中沒有資料可讀取,因為 cookie 已建立或失效。

    • FSCACHE_COOKIE_NEEDS_UPDATE - 一致性資料和/或物件大小已更改,需要提交。

    • FSCACHE_COOKIE_LOCAL_WRITE - netfs 的資料已在本地修改,因此快取物件可能與伺服器處於不一致狀態。

    • FSCACHE_COOKIE_HAVE_DATA - 如果後端成功將資料儲存到快取中,則應設定此標誌。

    • FSCACHE_COOKIE_RETIRED - cookie 在放棄時失效,快取的資料應丟棄。

  • debug_id - 用於在跟蹤點中記錄的除錯 ID。

  • inval_counter - 對 cookie 完成的失效次數。

  • advice - 有關如何使用 cookie 的資訊。

  • key_hash - 索引鍵的雜湊值。 無論 cpu 架構和位元組序如何,這都應該相同。

  • key_len - 索引鍵的長度。

  • aux_len - 一致性資料緩衝區的長度。

每個 cookie 都有一個索引鍵,可以內聯儲存到 cookie 或其他地方。 可以透過呼叫以下命令獲得指向此鍵的指標

void *fscache_get_key(struct fscache_cookie *cookie);

索引鍵是一個二進位制 blob,其儲存空間填充到 4 位元組的倍數。

每個 cookie 還有一個用於一致性資料的緩衝區。 這也可以內聯或與 cookie 分離,並且透過呼叫以下命令獲得指標

void *fscache_get_aux(struct fscache_cookie *cookie);

快取管理 API

快取後端透過提供 fscache 可以用來管理快取各個方面的操作表來實現快取管理 API。 這些儲存在型別的結構中

struct fscache_cache_ops {
        const char *name;
        ...
};

這包含快取後端驅動程式的可列印名稱,以及指向允許 fscache 請求管理快取的方法的許多指標

  • 設定卷 cookie [可選]

    void (*acquire_volume)(struct fscache_volume *volume);
    

    當建立卷 cookie 時會呼叫此方法。 呼叫者持有快取級別的訪問鎖,以防止快取在整個過程中消失。 此方法應設定訪問快取中卷的資源,並且在完成之前不應返回。

    如果成功,它可以將 cache_priv 設定為其自己的資料。

  • 清理卷 cookie [可選]

    void (*free_volume)(struct fscache_volume *volume);
    

    如果在設定了 cache_priv 的情況下釋放卷 cookie,則會呼叫此方法。

  • 在快取中查詢 cookie [強制]

    bool (*lookup_cookie)(struct fscache_cookie *cookie);
    

    呼叫此方法來查詢/建立訪問 cookie 的資料儲存所需的資源。 它從工作執行緒中呼叫,其中快取中具有卷級別的訪問鎖,以防止其被撤回。

    如果成功,則應返回 true,否則返回 false。 如果返回 false,則將呼叫 withdraw_cookie op(參見下文)。

    如果查詢失敗,但仍然可以建立物件(例如,之前沒有快取),則

    void fscache_cookie_lookup_negative(
            struct fscache_cookie *cookie);
    

    可以呼叫以允許網路檔案系統繼續並開始下載內容,同時快取後端繼續建立內容。

    如果成功,可以設定 cookie->cache_priv

  • 撤回沒有任何 cookie 訪問計數的物件 [強制]

    void (*withdraw_cookie)(struct fscache_cookie *cookie);
    

    呼叫此方法以從服務中撤回 cookie。 當 cookie 被 netfs 放棄、被快取後端撤回或剔除,或者在 fscache 長時間未使用後關閉時,將呼叫此方法。

    呼叫者不持有任何訪問鎖,但它是從不可重入的工作項中呼叫的,以管理各種撤回方式之間的競爭。

    如果應從快取中刪除關聯的資料,則 cookie 將設定 FSCACHE_COOKIE_RETIRED 標誌。

  • 更改資料儲存物件的大小 [強制]

    void (*resize_cookie)(struct netfs_cache_resources *cres,
                          loff_t new_size);
    

    呼叫此方法以通知快取後端由於本地截斷導致 netfs 檔案的大小發生更改。 快取後端應在返回之前進行所有需要進行的更改,因為這是在 netfs inode 互斥鎖下完成的。

    呼叫者持有 cookie 級別的訪問鎖,以防止與撤回發生競爭,並且 netfs 必須將 cookie 標記為正在使用,以防止垃圾回收或剔除刪除任何資源。

  • 使資料儲存物件失效 [強制]

    bool (*invalidate_cookie)(struct fscache_cookie *cookie);
    

    當網路檔案系統檢測到第三方修改或在本地進行 O_DIRECT 寫入時,將呼叫此方法。 這會請求快取後端丟棄快取中此物件的所有資料並重新開始。 如果成功,則應返回 true,否則返回 false。

    在進入時,新的 I O/操作被阻止。 一旦快取能夠再次接受 I/O,後端應透過呼叫以下命令釋放該塊

    void fscache_resume_after_invalidation(struct fscache_cookie *cookie);
    

    如果該方法返回 false,則將為此 cookie 撤回快取。

  • 準備對快取進行本地修改 [強制]

    void (*prepare_to_write)(struct fscache_cookie *cookie);
    

    當網路檔案系統發現它需要修改快取的內容(由於本地寫入或截斷)時,將呼叫此方法。 這使快取有機會注意到快取物件可能與伺服器不一致,並且可能需要在以後寫回。 如果未正確提交,這也可能導致快取的資料在以後的重新繫結時被丟棄。

  • 開始 netfs lib 的操作 [強制]

    bool (*begin_operation)(struct netfs_cache_resources *cres,
                            enum fscache_want_state want_state);
    

    在設定 I/O 操作(讀取、寫入或調整大小)時會呼叫此方法。 呼叫者持有 cookie 上的訪問鎖,並且必須將 cookie 標記為正在使用。

    如果可以,後端應將其需要保留的所有資源附加到 netfs_cache_resources 物件並返回 true。

    如果無法完成設定,則應返回 false。

    want_state 引數指示呼叫者需要快取物件處於的狀態以及它希望在操作期間執行的操作

    • FSCACHE_WANT_PARAMS - 呼叫者只想訪問快取物件引數;它不需要進行資料 I/O。

    • FSCACHE_WANT_READ - 呼叫者想要讀取資料。

    • FSCACHE_WANT_WRITE - 呼叫者想要寫入或調整快取物件的大小。

    請注意,如果 cookie 仍在建立中,則不一定有任何內容附加到 cookie 的 cache_priv。

資料 I/O API

快取後端透過 netfs 庫的 struct netfs_cache_ops(透過上面描述的 begin_operation 方法附加到 struct netfs_cache_resources)提供資料 I/O API。

有關說明,請參見網路檔案系統服務庫

其他函式

FS-Cache 提供了一些快取後端可能會使用的實用程式

  • 注意快取中發生的 I/O 錯誤

    void fscache_io_error(struct fscache_cache *cache);
    

    這告訴 FS-Cache 快取中發生了 I/O 錯誤。 這可以防止在快取上啟動任何新的 I/O。

    這實際上不會撤回快取。 必須單獨完成。

  • 注意由於故障而停止在 cookie 上進行快取

    void fscache_caching_failed(struct fscache_cookie *cookie);
    

    這說明在 cookie 上進行的快取以某種方式失敗,例如,後備儲存無法建立或失效失敗,並且在重置快取之前不應在其上進行進一步的 I/O 操作。

  • 計數 I/O 請求

    void fscache_count_read(void);
    void fscache_count_write(void);
    

    這些記錄從快取讀取和寫入快取。 這些數字顯示在 /proc/fs/fscache/stats 中。

  • 計數空間不足錯誤

    void fscache_count_no_write_space(void);
    void fscache_count_no_create_space(void);
    

    這些記錄快取中的 ENOSPC 錯誤,分為資料寫入失敗和檔案系統物件建立失敗(例如,mkdir)。

  • 計數剔除的物件

    void fscache_count_culled(void);
    

    這記錄了物件的剔除。

  • 從一組快取資源中獲取 cookie

    struct fscache_cookie *fscache_cres_cookie(struct netfs_cache_resources *cres)
    

    從快取資源中提取指向 cookie 的指標。 如果未設定 cookie,則這可能會返回 NULL cookie。

API 函式參考

讀取 cookie 的狀態

引數

struct fscache_cookie *cookie

要查詢的 cookie

說明

獲取 cookie 的狀態,在 cookie 內容和狀態值之間強制執行排序。 與 fscache_set_cookie_state() 配對使用。

void *fscache_get_key(struct fscache_cookie *cookie)

獲取指向 cookie 鍵的指標

引數

struct fscache_cookie *cookie

要查詢的 cookie

說明

返回一個指標,指向儲存 cookie 鍵的位置。

void fscache_count_object(struct fscache_cache *cache)

告知 fscache 已新增物件

引數

struct fscache_cache *cache

要記帳的快取

說明

告知 fscache 已將物件新增到快取中。 這可以防止快取在物件被取消計數之前拆除快取結構。

void fscache_uncount_object(struct fscache_cache *cache)

告知 fscache 已刪除物件

引數

struct fscache_cache *cache

要記帳的快取

說明

告知 fscache 已從快取中刪除物件,並且將不再訪問該物件。 在此之後,可能會銷燬快取 cookie。

void fscache_wait_for_objects(struct fscache_cache *cache)

等待撤回所有物件

引數

struct fscache_cache *cache

要查詢的快取

說明

等待快取中所有現存物件完成撤回並消失。