block/t10-pi.c

Source file repositories/reference/linux-study-clean/block/t10-pi.c

File Facts

System
Linux kernel
Corpus path
block/t10-pi.c
Extension
.c
Size
14771 bytes
Lines
568
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: implementation source
Status
source implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

struct blk_integrity_iter {
	struct bio			*bio;
	struct bio_integrity_payload	*bip;
	struct blk_integrity		*bi;
	struct bvec_iter		data_iter;
	struct bvec_iter		prot_iter;
	unsigned int			interval_remaining;
	u64				seed;
	u64				csum;
};

static void blk_calculate_guard(struct blk_integrity_iter *iter, void *data,
				unsigned int len)
{
	switch (iter->bi->csum_type) {
	case BLK_INTEGRITY_CSUM_CRC64:
		iter->csum = crc64_nvme(iter->csum, data, len);
		break;
	case BLK_INTEGRITY_CSUM_CRC:
		iter->csum = crc_t10dif_update(iter->csum, data, len);
		break;
	case BLK_INTEGRITY_CSUM_IP:
		iter->csum = (__force u32)csum_partial(data, len,
						(__force __wsum)iter->csum);
		break;
	default:
		WARN_ON_ONCE(1);
		iter->csum = U64_MAX;
		break;
	}
}

static void blk_integrity_csum_finish(struct blk_integrity_iter *iter)
{
	switch (iter->bi->csum_type) {
	case BLK_INTEGRITY_CSUM_IP:
		iter->csum = (__force u16)csum_fold((__force __wsum)iter->csum);
		break;
	default:
		break;
	}
}

/*
 * Update the csum for formats that have metadata padding in front of the data
 * integrity field
 */
static void blk_integrity_csum_offset(struct blk_integrity_iter *iter)
{
	unsigned int offset = iter->bi->pi_offset;
	struct bio_vec *bvec = iter->bip->bip_vec;

	while (offset > 0) {
		struct bio_vec pbv = bvec_iter_bvec(bvec, iter->prot_iter);
		unsigned int len = min(pbv.bv_len, offset);
		void *prot_buf = bvec_kmap_local(&pbv);

		blk_calculate_guard(iter, prot_buf, len);
		kunmap_local(prot_buf);
		offset -= len;
		bvec_iter_advance_single(bvec, &iter->prot_iter, len);
	}
	blk_integrity_csum_finish(iter);
}

static void blk_integrity_copy_from_tuple(struct bio_integrity_payload *bip,
					  struct bvec_iter *iter, void *tuple,
					  unsigned int tuple_size)
{
	while (tuple_size) {
		struct bio_vec pbv = bvec_iter_bvec(bip->bip_vec, *iter);
		unsigned int len = min(tuple_size, pbv.bv_len);
		void *prot_buf = bvec_kmap_local(&pbv);

		memcpy(prot_buf, tuple, len);
		kunmap_local(prot_buf);
		bvec_iter_advance_single(bip->bip_vec, iter, len);
		tuple_size -= len;
		tuple += len;
	}
}

static void blk_integrity_copy_to_tuple(struct bio_integrity_payload *bip,
					struct bvec_iter *iter, void *tuple,
					unsigned int tuple_size)
{
	while (tuple_size) {
		struct bio_vec pbv = bvec_iter_bvec(bip->bip_vec, *iter);
		unsigned int len = min(tuple_size, pbv.bv_len);
		void *prot_buf = bvec_kmap_local(&pbv);

Annotation

Implementation Notes