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