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