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 */
|