xref: /linux/drivers/md/dm-pcache/segment.h (revision 55a42f78ffd386e01a5404419f8c5ded7db70a21)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #ifndef _PCACHE_SEGMENT_H
3 #define _PCACHE_SEGMENT_H
4 
5 #include <linux/bio.h>
6 #include <linux/bitfield.h>
7 
8 #include "pcache_internal.h"
9 
10 struct pcache_segment_info {
11 	struct pcache_meta_header	header;
12 	__u32			flags;
13 	__u32			next_seg;
14 };
15 
16 #define PCACHE_SEG_INFO_FLAGS_HAS_NEXT		BIT(0)
17 
18 #define PCACHE_SEG_INFO_FLAGS_TYPE_MASK         GENMASK(4, 1)
19 #define PCACHE_SEGMENT_TYPE_CACHE_DATA		1
20 
21 static inline bool segment_info_has_next(struct pcache_segment_info *seg_info)
22 {
23 	return (seg_info->flags & PCACHE_SEG_INFO_FLAGS_HAS_NEXT);
24 }
25 
26 static inline void segment_info_set_type(struct pcache_segment_info *seg_info, u8 type)
27 {
28 	seg_info->flags &= ~PCACHE_SEG_INFO_FLAGS_TYPE_MASK;
29 	seg_info->flags |= FIELD_PREP(PCACHE_SEG_INFO_FLAGS_TYPE_MASK, type);
30 }
31 
32 static inline u8 segment_info_get_type(struct pcache_segment_info *seg_info)
33 {
34 	return FIELD_GET(PCACHE_SEG_INFO_FLAGS_TYPE_MASK, seg_info->flags);
35 }
36 
37 struct pcache_segment_pos {
38 	struct pcache_segment	*segment;	/* Segment associated with the position */
39 	u32			off;		/* Offset within the segment */
40 };
41 
42 struct pcache_segment_init_options {
43 	u8			type;
44 	u32			seg_id;
45 	u32			data_off;
46 
47 	struct pcache_segment_info	*seg_info;
48 };
49 
50 struct pcache_segment {
51 	struct pcache_cache_dev	*cache_dev;
52 
53 	void			*data;
54 	u32			data_size;
55 	u32			seg_id;
56 
57 	struct pcache_segment_info	*seg_info;
58 };
59 
60 int segment_copy_to_bio(struct pcache_segment *segment,
61 		      u32 data_off, u32 data_len, struct bio *bio, u32 bio_off);
62 int segment_copy_from_bio(struct pcache_segment *segment,
63 			u32 data_off, u32 data_len, struct bio *bio, u32 bio_off);
64 
65 static inline void segment_pos_advance(struct pcache_segment_pos *seg_pos, u32 len)
66 {
67 	BUG_ON(seg_pos->off + len > seg_pos->segment->data_size);
68 
69 	seg_pos->off += len;
70 }
71 
72 void pcache_segment_init(struct pcache_cache_dev *cache_dev, struct pcache_segment *segment,
73 		      struct pcache_segment_init_options *options);
74 #endif /* _PCACHE_SEGMENT_H */
75