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