1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_BLK_INTEGRITY_H |
3 | #define _LINUX_BLK_INTEGRITY_H |
4 | |
5 | #include <linux/blk-mq.h> |
6 | |
7 | struct request; |
8 | |
9 | enum blk_integrity_flags { |
10 | BLK_INTEGRITY_VERIFY = 1 << 0, |
11 | BLK_INTEGRITY_GENERATE = 1 << 1, |
12 | BLK_INTEGRITY_DEVICE_CAPABLE = 1 << 2, |
13 | BLK_INTEGRITY_IP_CHECKSUM = 1 << 3, |
14 | }; |
15 | |
16 | struct blk_integrity_iter { |
17 | void *prot_buf; |
18 | void *data_buf; |
19 | sector_t seed; |
20 | unsigned int data_size; |
21 | unsigned short interval; |
22 | unsigned char tuple_size; |
23 | const char *disk_name; |
24 | }; |
25 | |
26 | typedef blk_status_t (integrity_processing_fn) (struct blk_integrity_iter *); |
27 | typedef void (integrity_prepare_fn) (struct request *); |
28 | typedef void (integrity_complete_fn) (struct request *, unsigned int); |
29 | |
30 | struct blk_integrity_profile { |
31 | integrity_processing_fn *generate_fn; |
32 | integrity_processing_fn *verify_fn; |
33 | integrity_prepare_fn *prepare_fn; |
34 | integrity_complete_fn *complete_fn; |
35 | const char *name; |
36 | }; |
37 | |
38 | #ifdef CONFIG_BLK_DEV_INTEGRITY |
39 | void blk_integrity_register(struct gendisk *, struct blk_integrity *); |
40 | void blk_integrity_unregister(struct gendisk *); |
41 | int blk_integrity_compare(struct gendisk *, struct gendisk *); |
42 | int blk_rq_map_integrity_sg(struct request_queue *, struct bio *, |
43 | struct scatterlist *); |
44 | int blk_rq_count_integrity_sg(struct request_queue *, struct bio *); |
45 | |
46 | static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk) |
47 | { |
48 | struct blk_integrity *bi = &disk->queue->integrity; |
49 | |
50 | if (!bi->profile) |
51 | return NULL; |
52 | |
53 | return bi; |
54 | } |
55 | |
56 | static inline struct blk_integrity * |
57 | bdev_get_integrity(struct block_device *bdev) |
58 | { |
59 | return blk_get_integrity(disk: bdev->bd_disk); |
60 | } |
61 | |
62 | static inline bool |
63 | blk_integrity_queue_supports_integrity(struct request_queue *q) |
64 | { |
65 | return q->integrity.profile; |
66 | } |
67 | |
68 | static inline void blk_queue_max_integrity_segments(struct request_queue *q, |
69 | unsigned int segs) |
70 | { |
71 | q->limits.max_integrity_segments = segs; |
72 | } |
73 | |
74 | static inline unsigned short |
75 | queue_max_integrity_segments(const struct request_queue *q) |
76 | { |
77 | return q->limits.max_integrity_segments; |
78 | } |
79 | |
80 | /** |
81 | * bio_integrity_intervals - Return number of integrity intervals for a bio |
82 | * @bi: blk_integrity profile for device |
83 | * @sectors: Size of the bio in 512-byte sectors |
84 | * |
85 | * Description: The block layer calculates everything in 512 byte |
86 | * sectors but integrity metadata is done in terms of the data integrity |
87 | * interval size of the storage device. Convert the block layer sectors |
88 | * to the appropriate number of integrity intervals. |
89 | */ |
90 | static inline unsigned int bio_integrity_intervals(struct blk_integrity *bi, |
91 | unsigned int sectors) |
92 | { |
93 | return sectors >> (bi->interval_exp - 9); |
94 | } |
95 | |
96 | static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi, |
97 | unsigned int sectors) |
98 | { |
99 | return bio_integrity_intervals(bi, sectors) * bi->tuple_size; |
100 | } |
101 | |
102 | static inline bool blk_integrity_rq(struct request *rq) |
103 | { |
104 | return rq->cmd_flags & REQ_INTEGRITY; |
105 | } |
106 | |
107 | /* |
108 | * Return the first bvec that contains integrity data. Only drivers that are |
109 | * limited to a single integrity segment should use this helper. |
110 | */ |
111 | static inline struct bio_vec *rq_integrity_vec(struct request *rq) |
112 | { |
113 | if (WARN_ON_ONCE(queue_max_integrity_segments(rq->q) > 1)) |
114 | return NULL; |
115 | return rq->bio->bi_integrity->bip_vec; |
116 | } |
117 | #else /* CONFIG_BLK_DEV_INTEGRITY */ |
118 | static inline int blk_rq_count_integrity_sg(struct request_queue *q, |
119 | struct bio *b) |
120 | { |
121 | return 0; |
122 | } |
123 | static inline int blk_rq_map_integrity_sg(struct request_queue *q, |
124 | struct bio *b, |
125 | struct scatterlist *s) |
126 | { |
127 | return 0; |
128 | } |
129 | static inline struct blk_integrity *bdev_get_integrity(struct block_device *b) |
130 | { |
131 | return NULL; |
132 | } |
133 | static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk) |
134 | { |
135 | return NULL; |
136 | } |
137 | static inline bool |
138 | blk_integrity_queue_supports_integrity(struct request_queue *q) |
139 | { |
140 | return false; |
141 | } |
142 | static inline int blk_integrity_compare(struct gendisk *a, struct gendisk *b) |
143 | { |
144 | return 0; |
145 | } |
146 | static inline void blk_integrity_register(struct gendisk *d, |
147 | struct blk_integrity *b) |
148 | { |
149 | } |
150 | static inline void blk_integrity_unregister(struct gendisk *d) |
151 | { |
152 | } |
153 | static inline void blk_queue_max_integrity_segments(struct request_queue *q, |
154 | unsigned int segs) |
155 | { |
156 | } |
157 | static inline unsigned short |
158 | queue_max_integrity_segments(const struct request_queue *q) |
159 | { |
160 | return 0; |
161 | } |
162 | |
163 | static inline unsigned int bio_integrity_intervals(struct blk_integrity *bi, |
164 | unsigned int sectors) |
165 | { |
166 | return 0; |
167 | } |
168 | |
169 | static inline unsigned int bio_integrity_bytes(struct blk_integrity *bi, |
170 | unsigned int sectors) |
171 | { |
172 | return 0; |
173 | } |
174 | static inline int blk_integrity_rq(struct request *rq) |
175 | { |
176 | return 0; |
177 | } |
178 | |
179 | static inline struct bio_vec *rq_integrity_vec(struct request *rq) |
180 | { |
181 | return NULL; |
182 | } |
183 | #endif /* CONFIG_BLK_DEV_INTEGRITY */ |
184 | #endif /* _LINUX_BLK_INTEGRITY_H */ |
185 | |