LCOV - code coverage report
Current view: top level - dm-pcache - cache.h (source / functions) Coverage Total Hit
Test: dm_pcache.info Lines: 100.0 % 94 94
Test Date: 2025-08-08 03:56:04 Functions: 100.0 % 11 11
Legend: Lines: hit not hit

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-2.0-or-later */
       2              : #ifndef _PCACHE_CACHE_H
       3              : #define _PCACHE_CACHE_H
       4              : 
       5              : #include "segment.h"
       6              : 
       7              : /* Garbage collection thresholds */
       8              : #define PCACHE_CACHE_GC_PERCENT_MIN       0                   /* Minimum GC percentage */
       9              : #define PCACHE_CACHE_GC_PERCENT_MAX       90                  /* Maximum GC percentage */
      10              : #define PCACHE_CACHE_GC_PERCENT_DEFAULT   70                  /* Default GC percentage */
      11              : 
      12              : #define PCACHE_CACHE_SUBTREE_SIZE               (4 * PCACHE_MB)     /* 4MB total tree size */
      13              : #define PCACHE_CACHE_SUBTREE_SIZE_MASK          0x3FFFFF            /* Mask for tree size */
      14              : #define PCACHE_CACHE_SUBTREE_SIZE_SHIFT         22                  /* Bit shift for tree size */
      15              : 
      16              : /* Maximum number of keys per key set */
      17              : #define PCACHE_KSET_KEYS_MAX            128
      18              : #define PCACHE_CACHE_SEGS_MAX           (1024 * 1024)   /* maximum cache size for each device is 16T */
      19              : #define PCACHE_KSET_ONMEDIA_SIZE_MAX    struct_size_t(struct pcache_cache_kset_onmedia, data, PCACHE_KSET_KEYS_MAX)
      20              : #define PCACHE_KSET_SIZE                (sizeof(struct pcache_cache_kset) + sizeof(struct pcache_cache_key_onmedia) * PCACHE_KSET_KEYS_MAX)
      21              : 
      22              : /* Maximum number of keys to clean in one round of clean_work */
      23              : #define PCACHE_CLEAN_KEYS_MAX             10
      24              : 
      25              : /* Writeback and garbage collection intervals in jiffies */
      26              : #define PCACHE_CACHE_WRITEBACK_INTERVAL   (5 * HZ)
      27              : #define PCACHE_CACHE_GC_INTERVAL          (5 * HZ)
      28              : 
      29              : /* Macro to get the cache key structure from an rb_node pointer */
      30              : #define CACHE_KEY(node)                (container_of(node, struct pcache_cache_key, rb_node))
      31              : 
      32              : struct pcache_cache_pos_onmedia {
      33              :         struct pcache_meta_header header;
      34              :         __u32 cache_seg_id;
      35              :         __u32 seg_off;
      36              : };
      37              : 
      38              : /* Offset and size definitions for cache segment control */
      39              : #define PCACHE_CACHE_SEG_CTRL_OFF     (PCACHE_SEG_INFO_SIZE * PCACHE_META_INDEX_MAX)
      40              : #define PCACHE_CACHE_SEG_CTRL_SIZE    (4 * PCACHE_KB)
      41              : 
      42              : struct pcache_cache_seg_gen {
      43              :         struct pcache_meta_header header;
      44              :         __u64 gen;
      45              : };
      46              : 
      47              : /* Control structure for cache segments */
      48              : struct pcache_cache_seg_ctrl {
      49              :         struct pcache_cache_seg_gen gen[PCACHE_META_INDEX_MAX];
      50              :         __u64   res[64];
      51              : };
      52              : 
      53              : #define PCACHE_CACHE_FLAGS_DATA_CRC                     BIT(0)
      54              : #define PCACHE_CACHE_FLAGS_INIT_DONE                    BIT(1)
      55              : 
      56              : #define PCACHE_CACHE_FLAGS_CACHE_MODE_MASK              GENMASK(5, 2)
      57              : #define PCACHE_CACHE_MODE_WRITEBACK                     0
      58              : #define PCACHE_CACHE_MODE_WRITETHROUGH                  1
      59              : #define PCACHE_CACHE_MODE_WRITEAROUND                   2
      60              : #define PCACHE_CACHE_MODE_WRITEONLY                     3
      61              : 
      62              : #define PCACHE_CACHE_FLAGS_GC_PERCENT_MASK              GENMASK(12, 6)
      63              : 
      64              : struct pcache_cache_info {
      65              :         struct pcache_meta_header header;
      66              :         __u32 seg_id;
      67              :         __u32 n_segs;
      68              :         __u32 flags;
      69              :         __u32 reserved;
      70              : };
      71              : 
      72              : struct pcache_cache_pos {
      73              :         struct pcache_cache_segment *cache_seg;
      74              :         u32 seg_off;
      75              : };
      76              : 
      77              : struct pcache_cache_segment {
      78              :         struct pcache_cache     *cache;
      79              :         u32                     cache_seg_id;   /* Index in cache->segments */
      80              :         struct pcache_segment   segment;
      81              :         atomic_t                refs;
      82              : 
      83              :         struct pcache_segment_info cache_seg_info;
      84              :         struct mutex            info_lock;
      85              :         u32                     info_index;
      86              : 
      87              :         spinlock_t              gen_lock;
      88              :         u64                     gen;
      89              :         u64                     gen_seq;
      90              :         u32                     gen_index;
      91              : 
      92              :         struct pcache_cache_seg_ctrl *cache_seg_ctrl;
      93              :         struct mutex            ctrl_lock;
      94              : };
      95              : 
      96              : /* rbtree for cache entries */
      97              : struct pcache_cache_subtree {
      98              :         struct rb_root root;
      99              :         spinlock_t tree_lock;
     100              : };
     101              : 
     102              : struct pcache_cache_tree {
     103              :         struct pcache_cache             *cache;
     104              :         u32                             n_subtrees;
     105              :         mempool_t                       key_pool;
     106              :         struct pcache_cache_subtree     *subtrees;
     107              : };
     108              : 
     109              : extern struct kmem_cache *key_cache;
     110              : 
     111              : struct pcache_cache_key {
     112              :         struct pcache_cache_tree        *cache_tree;
     113              :         struct pcache_cache_subtree     *cache_subtree;
     114              :         struct kref                     ref;
     115              :         struct rb_node                  rb_node;
     116              :         struct list_head                list_node;
     117              :         u64                             off;
     118              :         u32                             len;
     119              :         u32                             flags;
     120              :         struct pcache_cache_pos         cache_pos;
     121              :         u64                             seg_gen;
     122              : };
     123              : 
     124              : #define PCACHE_CACHE_KEY_FLAGS_EMPTY            BIT(0)
     125              : #define PCACHE_CACHE_KEY_FLAGS_CLEAN            BIT(1)
     126              : 
     127              : struct pcache_cache_key_onmedia {
     128              :         __u64 off;
     129              :         __u32 len;
     130              :         __u32 flags;
     131              :         __u32 cache_seg_id;
     132              :         __u32 cache_seg_off;
     133              :         __u64 seg_gen;
     134              :         __u32 data_crc;
     135              :         __u32 reserved;
     136              : };
     137              : 
     138              : struct pcache_cache_kset_onmedia {
     139              :         __u32 crc;
     140              :         union {
     141              :                 __u32 key_num;
     142              :                 __u32 next_cache_seg_id;
     143              :         };
     144              :         __u64 magic;
     145              :         __u64 flags;
     146              :         struct pcache_cache_key_onmedia data[];
     147              : };
     148              : 
     149              : struct pcache_cache {
     150              :         struct pcache_backing_dev       *backing_dev;
     151              :         struct pcache_cache_dev         *cache_dev;
     152              :         struct pcache_cache_ctrl        *cache_ctrl;
     153              :         u64                             dev_size;
     154              : 
     155              :         struct pcache_cache_data_head __percpu *data_heads;
     156              : 
     157              :         spinlock_t              key_head_lock;
     158              :         struct pcache_cache_pos key_head;
     159              :         u32                     n_ksets;
     160              :         struct pcache_cache_kset        *ksets;
     161              : 
     162              :         struct mutex            key_tail_lock;
     163              :         struct pcache_cache_pos key_tail;
     164              :         u64                     key_tail_seq;
     165              :         u32                     key_tail_index;
     166              : 
     167              :         struct mutex            dirty_tail_lock;
     168              :         struct pcache_cache_pos dirty_tail;
     169              :         u64                     dirty_tail_seq;
     170              :         u32                     dirty_tail_index;
     171              : 
     172              :         struct pcache_cache_tree        req_key_tree;
     173              :         struct work_struct      clean_work;
     174              : 
     175              :         struct mutex            writeback_lock;
     176              :         char wb_kset_onmedia_buf[PCACHE_KSET_ONMEDIA_SIZE_MAX];
     177              :         struct pcache_cache_tree        writeback_key_tree;
     178              :         struct delayed_work     writeback_work;
     179              :         struct {
     180              :                 atomic_t pending;
     181              :                 u32 advance;
     182              :                 int ret;
     183              :         } writeback_ctx;
     184              : 
     185              :         char gc_kset_onmedia_buf[PCACHE_KSET_ONMEDIA_SIZE_MAX];
     186              :         struct delayed_work     gc_work;
     187              :         atomic_t                gc_errors;
     188              : 
     189              :         struct mutex                    cache_info_lock;
     190              :         struct pcache_cache_info        cache_info;
     191              :         struct pcache_cache_info        *cache_info_addr;
     192              :         u32                             info_index;
     193              : 
     194              :         u32                     n_segs;
     195              :         unsigned long           *seg_map;
     196              :         u32                     last_cache_seg;
     197              :         bool                    cache_full;
     198              :         spinlock_t              seg_map_lock;
     199              :         struct pcache_cache_segment *segments;
     200              : };
     201              : 
     202              : struct workqueue_struct *cache_get_wq(struct pcache_cache *cache);
     203              : 
     204              : struct dm_pcache;
     205              : struct pcache_cache_options {
     206              :         u32     cache_mode:4;
     207              :         u32     data_crc:1;
     208              : };
     209              : int pcache_cache_start(struct dm_pcache *pcache);
     210              : void pcache_cache_stop(struct dm_pcache *pcache);
     211              : 
     212              : struct pcache_cache_ctrl {
     213              :         /* Updated by gc_thread */
     214              :         struct pcache_cache_pos_onmedia key_tail_pos[PCACHE_META_INDEX_MAX];
     215              : 
     216              :         /* Updated by writeback_thread */
     217              :         struct pcache_cache_pos_onmedia dirty_tail_pos[PCACHE_META_INDEX_MAX];
     218              : };
     219              : 
     220              : struct pcache_cache_data_head {
     221              :         struct pcache_cache_pos head_pos;
     222              : };
     223              : 
     224      4857438 : static inline u16 pcache_cache_get_gc_percent(struct pcache_cache *cache)
     225              : {
     226      4857438 :         return FIELD_GET(PCACHE_CACHE_FLAGS_GC_PERCENT_MASK, cache->cache_info.flags);
     227              : }
     228              : 
     229              : int pcache_cache_set_gc_percent(struct pcache_cache *cache, u8 percent);
     230              : 
     231              : /* cache key */
     232              : struct pcache_cache_key *cache_key_alloc(struct pcache_cache_tree *cache_tree, gfp_t gfp_mask);
     233              : void cache_key_init(struct pcache_cache_tree *cache_tree, struct pcache_cache_key *key);
     234              : void cache_key_get(struct pcache_cache_key *key);
     235              : void cache_key_put(struct pcache_cache_key *key);
     236              : int cache_key_append(struct pcache_cache *cache, struct pcache_cache_key *key, bool force_close);
     237              : void cache_key_insert(struct pcache_cache_tree *cache_tree, struct pcache_cache_key *key, bool fixup);
     238              : int cache_key_decode(struct pcache_cache *cache,
     239              :                         struct pcache_cache_key_onmedia *key_onmedia,
     240              :                         struct pcache_cache_key *key);
     241              : void cache_pos_advance(struct pcache_cache_pos *pos, u32 len);
     242              : 
     243              : #define PCACHE_KSET_FLAGS_LAST          BIT(0)
     244              : #define PCACHE_KSET_MAGIC               0x676894a64e164f1aULL
     245              : 
     246              : struct pcache_cache_kset {
     247              :         struct pcache_cache *cache;
     248              :         spinlock_t        kset_lock;
     249              :         struct delayed_work flush_work;
     250              :         struct pcache_cache_kset_onmedia kset_onmedia;
     251              : };
     252              : 
     253              : extern struct pcache_cache_kset_onmedia pcache_empty_kset;
     254              : 
     255              : #define SUBTREE_WALK_RET_OK             0
     256              : #define SUBTREE_WALK_RET_ERR            1
     257              : #define SUBTREE_WALK_RET_NEED_KEY       2
     258              : #define SUBTREE_WALK_RET_NEED_REQ       3
     259              : #define SUBTREE_WALK_RET_RESEARCH       4
     260              : 
     261              : struct pcache_cache_subtree_walk_ctx {
     262              :         struct pcache_cache_tree *cache_tree;
     263              :         struct rb_node *start_node;
     264              :         struct pcache_request *pcache_req;
     265              :         struct pcache_cache_key *key;
     266              :         u32     req_done;
     267              :         int     ret;
     268              : 
     269              :         /* pre-allocated key and backing_dev_req */
     270              :         struct pcache_cache_key         *pre_alloc_key;
     271              :         struct pcache_backing_dev_req   *pre_alloc_req;
     272              : 
     273              :         struct list_head *delete_key_list;
     274              :         struct list_head *submit_req_list;
     275              : 
     276              :         /*
     277              :          *        |--------|            key_tmp
     278              :          * |====|                       key
     279              :          */
     280              :         int (*before)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp,
     281              :                         struct pcache_cache_subtree_walk_ctx *ctx);
     282              : 
     283              :         /*
     284              :          * |----------|                 key_tmp
     285              :          *              |=====|         key
     286              :          */
     287              :         int (*after)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp,
     288              :                         struct pcache_cache_subtree_walk_ctx *ctx);
     289              : 
     290              :         /*
     291              :          *     |----------------|       key_tmp
     292              :          * |===========|                key
     293              :          */
     294              :         int (*overlap_tail)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp,
     295              :                         struct pcache_cache_subtree_walk_ctx *ctx);
     296              : 
     297              :         /*
     298              :          * |--------|                   key_tmp
     299              :          *   |==========|               key
     300              :          */
     301              :         int (*overlap_head)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp,
     302              :                         struct pcache_cache_subtree_walk_ctx *ctx);
     303              : 
     304              :         /*
     305              :          *    |----|                    key_tmp
     306              :          * |==========|                 key
     307              :          */
     308              :         int (*overlap_contain)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp,
     309              :                         struct pcache_cache_subtree_walk_ctx *ctx);
     310              : 
     311              :         /*
     312              :          * |-----------|                key_tmp
     313              :          *   |====|                     key
     314              :          */
     315              :         int (*overlap_contained)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp,
     316              :                         struct pcache_cache_subtree_walk_ctx *ctx);
     317              : 
     318              :         int (*walk_finally)(struct pcache_cache_subtree_walk_ctx *ctx, int ret);
     319              :         bool (*walk_done)(struct pcache_cache_subtree_walk_ctx *ctx);
     320              : };
     321              : 
     322              : int cache_subtree_walk(struct pcache_cache_subtree_walk_ctx *ctx);
     323              : struct rb_node *cache_subtree_search(struct pcache_cache_subtree *cache_subtree, struct pcache_cache_key *key,
     324              :                                   struct rb_node **parentp, struct rb_node ***newp,
     325              :                                   struct list_head *delete_key_list);
     326              : int cache_kset_close(struct pcache_cache *cache, struct pcache_cache_kset *kset);
     327              : void clean_fn(struct work_struct *work);
     328              : void kset_flush_fn(struct work_struct *work);
     329              : int cache_replay(struct pcache_cache *cache);
     330              : int cache_tree_init(struct pcache_cache *cache, struct pcache_cache_tree *cache_tree, u32 n_subtrees);
     331              : void cache_tree_clear(struct pcache_cache_tree *cache_tree);
     332              : void cache_tree_exit(struct pcache_cache_tree *cache_tree);
     333              : 
     334              : /* cache segments */
     335              : struct pcache_cache_segment *get_cache_segment(struct pcache_cache *cache);
     336              : int cache_seg_init(struct pcache_cache *cache, u32 seg_id, u32 cache_seg_id,
     337              :                    bool new_cache);
     338              : void cache_seg_get(struct pcache_cache_segment *cache_seg);
     339              : void cache_seg_put(struct pcache_cache_segment *cache_seg);
     340              : void cache_seg_set_next_seg(struct pcache_cache_segment *cache_seg, u32 seg_id);
     341              : 
     342              : /* cache request*/
     343              : int cache_flush(struct pcache_cache *cache);
     344              : void miss_read_end_work_fn(struct work_struct *work);
     345              : int pcache_cache_handle_req(struct pcache_cache *cache, struct pcache_request *pcache_req);
     346              : 
     347              : /* gc */
     348              : void pcache_cache_gc_fn(struct work_struct *work);
     349              : 
     350              : /* writeback */
     351              : void cache_writeback_exit(struct pcache_cache *cache);
     352              : int cache_writeback_init(struct pcache_cache *cache);
     353              : void cache_writeback_fn(struct work_struct *work);
     354              : 
     355              : /* inline functions */
     356    213734702 : static inline struct pcache_cache_subtree *get_subtree(struct pcache_cache_tree *cache_tree, u64 off)
     357              : {
     358    213734702 :         if (cache_tree->n_subtrees == 1)
     359     74089267 :                 return &cache_tree->subtrees[0];
     360              : 
     361    139645435 :         return &cache_tree->subtrees[off >> PCACHE_CACHE_SUBTREE_SIZE_SHIFT];
     362              : }
     363              : 
     364    116241810 : static inline void *cache_pos_addr(struct pcache_cache_pos *pos)
     365              : {
     366     35453368 :         return (pos->cache_seg->segment.data + pos->seg_off);
     367              : }
     368              : 
     369     10785333 : static inline void *get_key_head_addr(struct pcache_cache *cache)
     370              : {
     371      5392711 :         return cache_pos_addr(&cache->key_head);
     372              : }
     373              : 
     374     41311915 : static inline u32 get_kset_id(struct pcache_cache *cache, u64 off)
     375              : {
     376     41311915 :         return (off >> PCACHE_CACHE_SUBTREE_SIZE_SHIFT) % cache->n_ksets;
     377              : }
     378              : 
     379    104589524 : static inline struct pcache_cache_kset *get_kset(struct pcache_cache *cache, u32 kset_id)
     380              : {
     381    104589524 :         return (void *)cache->ksets + PCACHE_KSET_SIZE * kset_id;
     382              : }
     383              : 
     384     61550858 : static inline struct pcache_cache_data_head *get_data_head(struct pcache_cache *cache)
     385              : {
     386     61550858 :         return this_cpu_ptr(cache->data_heads);
     387              : }
     388              : 
     389   1976203301 : static inline bool cache_key_empty(struct pcache_cache_key *key)
     390              : {
     391     91501576 :         return key->flags & PCACHE_CACHE_KEY_FLAGS_EMPTY;
     392              : }
     393              : 
     394     25892620 : static inline bool cache_key_clean(struct pcache_cache_key *key)
     395              : {
     396     25892620 :         return key->flags & PCACHE_CACHE_KEY_FLAGS_CLEAN;
     397              : }
     398              : 
     399     66736511 : static inline void cache_pos_copy(struct pcache_cache_pos *dst, struct pcache_cache_pos *src)
     400              : {
     401     66736511 :         memcpy(dst, src, sizeof(struct pcache_cache_pos));
     402     66736511 : }
     403              : 
     404              : /**
     405              :  * cache_seg_is_ctrl_seg - Checks if a cache segment is a cache ctrl segment.
     406              :  * @cache_seg_id: ID of the cache segment.
     407              :  *
     408              :  * Returns true if the cache segment ID corresponds to a cache ctrl segment.
     409              :  *
     410              :  * Note: We extend the segment control of the first cache segment
     411              :  * (cache segment ID 0) to serve as the cache control (pcache_cache_ctrl)
     412              :  * for the entire PCACHE cache. This function determines whether the given
     413              :  * cache segment is the one storing the pcache_cache_ctrl information.
     414              :  */
     415              : static inline bool cache_seg_is_ctrl_seg(u32 cache_seg_id)
     416              : {
     417              :         return (cache_seg_id == 0);
     418              : }
     419              : 
     420              : /**
     421              :  * cache_key_cutfront - Cuts a specified length from the front of a cache key.
     422              :  * @key: Pointer to pcache_cache_key structure.
     423              :  * @cut_len: Length to cut from the front.
     424              :  *
     425              :  * Advances the cache key position by cut_len and adjusts offset and length accordingly.
     426              :  */
     427     74310577 : static inline void cache_key_cutfront(struct pcache_cache_key *key, u32 cut_len)
     428              : {
     429     74310577 :         if (key->cache_pos.cache_seg)
     430     45730443 :                 cache_pos_advance(&key->cache_pos, cut_len);
     431              : 
     432     74310577 :         key->off += cut_len;
     433     74310577 :         key->len -= cut_len;
     434     74310577 : }
     435              : 
     436              : /**
     437              :  * cache_key_cutback - Cuts a specified length from the back of a cache key.
     438              :  * @key: Pointer to pcache_cache_key structure.
     439              :  * @cut_len: Length to cut from the back.
     440              :  *
     441              :  * Reduces the length of the cache key by cut_len.
     442              :  */
     443      7154308 : static inline void cache_key_cutback(struct pcache_cache_key *key, u32 cut_len)
     444              : {
     445      7154308 :         key->len -= cut_len;
     446              : }
     447              : 
     448    104708013 : static inline void cache_key_delete(struct pcache_cache_key *key)
     449              : {
     450    104708013 :         struct pcache_cache_subtree *cache_subtree;
     451              : 
     452    104708013 :         cache_subtree = key->cache_subtree;
     453    104708013 :         BUG_ON(!cache_subtree);
     454              : 
     455    104708013 :         rb_erase(&key->rb_node, &cache_subtree->root);
     456    104620423 :         key->flags = 0;
     457    104620423 :         cache_key_put(key);
     458    105141516 : }
     459              : 
     460    127749734 : static inline bool cache_data_crc_on(struct pcache_cache *cache)
     461              : {
     462    127749734 :         return (cache->cache_info.flags & PCACHE_CACHE_FLAGS_DATA_CRC);
     463              : }
     464              : 
     465              : static inline u32 cache_mode_get(struct pcache_cache *cache)
     466              : {
     467              :         return FIELD_GET(PCACHE_CACHE_FLAGS_CACHE_MODE_MASK, cache->cache_info.flags);
     468              : }
     469              : 
     470          268 : static inline void cache_mode_set(struct pcache_cache *cache, u32 cache_mode)
     471              : {
     472          268 :         cache->cache_info.flags &= ~PCACHE_CACHE_FLAGS_CACHE_MODE_MASK;
     473          268 :         cache->cache_info.flags |= FIELD_PREP(PCACHE_CACHE_FLAGS_CACHE_MODE_MASK, cache_mode);
     474          268 : }
     475              : 
     476              : /**
     477              :  * cache_key_data_crc - Calculates CRC for data in a cache key.
     478              :  * @key: Pointer to the pcache_cache_key structure.
     479              :  *
     480              :  * Returns the CRC-32 checksum of the data within the cache key's position.
     481              :  */
     482     70003109 : static inline u32 cache_key_data_crc(struct pcache_cache_key *key)
     483              : {
     484     70003109 :         void *data;
     485              : 
     486     70003109 :         data = cache_pos_addr(&key->cache_pos);
     487              : 
     488     70003109 :         return crc32c(PCACHE_CRC_SEED, data, key->len);
     489              : }
     490              : 
     491     15554324 : static inline u32 cache_kset_crc(struct pcache_cache_kset_onmedia *kset_onmedia)
     492              : {
     493     15554324 :         u32 crc_size;
     494              : 
     495     15554324 :         if (kset_onmedia->flags & PCACHE_KSET_FLAGS_LAST)
     496              :                 crc_size = sizeof(struct pcache_cache_kset_onmedia) - 4;
     497              :         else
     498     15554074 :                 crc_size = struct_size(kset_onmedia, data, kset_onmedia->key_num) - 4;
     499              : 
     500     15554324 :         return crc32c(PCACHE_CRC_SEED, (void *)kset_onmedia + 4, crc_size);
     501              : }
     502              : 
     503     10156565 : static inline u32 get_kset_onmedia_size(struct pcache_cache_kset_onmedia *kset_onmedia)
     504              : {
     505     10156565 :         return struct_size_t(struct pcache_cache_kset_onmedia, data, kset_onmedia->key_num);
     506              : }
     507              : 
     508              : /**
     509              :  * cache_seg_remain - Computes remaining space in a cache segment.
     510              :  * @pos: Pointer to pcache_cache_pos structure.
     511              :  *
     512              :  * Returns the amount of remaining space in the segment data starting from
     513              :  * the current position offset.
     514              :  */
     515    180133898 : static inline u32 cache_seg_remain(struct pcache_cache_pos *pos)
     516              : {
     517    180133898 :         struct pcache_cache_segment *cache_seg;
     518    180133898 :         struct pcache_segment *segment;
     519    180133898 :         u32 seg_remain;
     520              : 
     521    180133898 :         cache_seg = pos->cache_seg;
     522    180133898 :         segment = &cache_seg->segment;
     523    180133898 :         seg_remain = segment->data_size - pos->seg_off;
     524              : 
     525    180133898 :         return seg_remain;
     526              : }
     527              : 
     528              : /**
     529              :  * cache_key_invalid - Checks if a cache key is invalid.
     530              :  * @key: Pointer to pcache_cache_key structure.
     531              :  *
     532              :  * Returns true if the cache key is invalid due to its generation being
     533              :  * less than the generation of its segment; otherwise returns false.
     534              :  *
     535              :  * When the GC (garbage collection) thread identifies a segment
     536              :  * as reclaimable, it increments the segment's generation (gen). However,
     537              :  * it does not immediately remove all related cache keys. When accessing
     538              :  * such a cache key, this function can be used to determine if the cache
     539              :  * key has already become invalid.
     540              :  */
     541   1838934732 : static inline bool cache_key_invalid(struct pcache_cache_key *key)
     542              : {
     543   1838934732 :         if (cache_key_empty(key))
     544              :                 return false;
     545              : 
     546   1835286953 :         return (key->seg_gen < key->cache_pos.cache_seg->gen);
     547              : }
     548              : 
     549              : /**
     550              :  * cache_key_lstart - Retrieves the logical start offset of a cache key.
     551              :  * @key: Pointer to pcache_cache_key structure.
     552              :  *
     553              :  * Returns the logical start offset for the cache key.
     554              :  */
     555    374538266 : static inline u64 cache_key_lstart(struct pcache_cache_key *key)
     556              : {
     557    366446402 :         return key->off;
     558              : }
     559              : 
     560              : /**
     561              :  * cache_key_lend - Retrieves the logical end offset of a cache key.
     562              :  * @key: Pointer to pcache_cache_key structure.
     563              :  *
     564              :  * Returns the logical end offset for the cache key.
     565              :  */
     566    508958433 : static inline u64 cache_key_lend(struct pcache_cache_key *key)
     567              : {
     568    347488204 :         return key->off + key->len;
     569              : }
     570              : 
     571      5163437 : static inline void cache_key_copy(struct pcache_cache_key *key_dst, struct pcache_cache_key *key_src)
     572              : {
     573      5163437 :         key_dst->off = key_src->off;
     574      5163437 :         key_dst->len = key_src->len;
     575      5163437 :         key_dst->seg_gen = key_src->seg_gen;
     576      5163437 :         key_dst->cache_tree = key_src->cache_tree;
     577      5163437 :         key_dst->cache_subtree = key_src->cache_subtree;
     578      5163437 :         key_dst->flags = key_src->flags;
     579              : 
     580      5163437 :         cache_pos_copy(&key_dst->cache_pos, &key_src->cache_pos);
     581      5162657 : }
     582              : 
     583              : /**
     584              :  * cache_pos_onmedia_crc - Calculates the CRC for an on-media cache position.
     585              :  * @pos_om: Pointer to pcache_cache_pos_onmedia structure.
     586              :  *
     587              :  * Calculates the CRC-32 checksum of the position, excluding the first 4 bytes.
     588              :  * Returns the computed CRC value.
     589              :  */
     590     10003910 : static inline u32 cache_pos_onmedia_crc(struct pcache_cache_pos_onmedia *pos_om)
     591              : {
     592     10003910 :         return pcache_meta_crc(&pos_om->header, sizeof(struct pcache_cache_pos_onmedia));
     593              : }
     594              : 
     595              : void cache_pos_encode(struct pcache_cache *cache,
     596              :                              struct pcache_cache_pos_onmedia *pos_onmedia,
     597              :                              struct pcache_cache_pos *pos, u64 seq, u32 *index);
     598              : int cache_pos_decode(struct pcache_cache *cache,
     599              :                             struct pcache_cache_pos_onmedia *pos_onmedia,
     600              :                             struct pcache_cache_pos *pos, u64 *seq, u32 *index);
     601              : 
     602      4852599 : static inline void cache_encode_key_tail(struct pcache_cache *cache)
     603              : {
     604      4852599 :         cache_pos_encode(cache, cache->cache_ctrl->key_tail_pos,
     605      4852599 :                         &cache->key_tail, ++cache->key_tail_seq,
     606              :                         &cache->key_tail_index);
     607      4850640 : }
     608              : 
     609          129 : static inline int cache_decode_key_tail(struct pcache_cache *cache)
     610              : {
     611          129 :         return cache_pos_decode(cache, cache->cache_ctrl->key_tail_pos,
     612              :                                 &cache->key_tail, &cache->key_tail_seq,
     613              :                                 &cache->key_tail_index);
     614              : }
     615              : 
     616      5151973 : static inline void cache_encode_dirty_tail(struct pcache_cache *cache)
     617              : {
     618      5151973 :         cache_pos_encode(cache, cache->cache_ctrl->dirty_tail_pos,
     619      5151973 :                         &cache->dirty_tail, ++cache->dirty_tail_seq,
     620              :                         &cache->dirty_tail_index);
     621      5151822 : }
     622              : 
     623          129 : static inline int cache_decode_dirty_tail(struct pcache_cache *cache)
     624              : {
     625          129 :         return cache_pos_decode(cache, cache->cache_ctrl->dirty_tail_pos,
     626              :                                 &cache->dirty_tail, &cache->dirty_tail_seq,
     627              :                                 &cache->dirty_tail_index);
     628              : }
     629              : 
     630              : int pcache_cache_init(void);
     631              : void pcache_cache_exit(void);
     632              : #endif /* _PCACHE_CACHE_H */
        

Generated by: LCOV version 2.0-1