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