block/blk-settings.c

Source file repositories/reference/linux-study-clean/block/blk-settings.c

File Facts

System
Linux kernel
Corpus path
block/blk-settings.c
Extension
.c
Size
33724 bytes
Lines
1056
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: exported/initcall integration point
Status
integration 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

if (bi->pi_tuple_size) {
			pr_warn("pi_tuple_size must be 0 when checksum type is none\n");
			return -EINVAL;
		}
		break;
	case BLK_INTEGRITY_CSUM_CRC:
	case BLK_INTEGRITY_CSUM_IP:
		if (bi->pi_tuple_size != sizeof(struct t10_pi_tuple)) {
			pr_warn("pi_tuple_size mismatch for T10 PI: expected %zu, got %u\n",
				 sizeof(struct t10_pi_tuple),
				 bi->pi_tuple_size);
			return -EINVAL;
		}
		break;
	case BLK_INTEGRITY_CSUM_CRC64:
		if (bi->pi_tuple_size != sizeof(struct crc64_pi_tuple)) {
			pr_warn("pi_tuple_size mismatch for CRC64 PI: expected %zu, got %u\n",
				 sizeof(struct crc64_pi_tuple),
				 bi->pi_tuple_size);
			return -EINVAL;
		}
		break;
	}

	if (!bi->interval_exp) {
		bi->interval_exp = ilog2(lim->logical_block_size);
	} else if (bi->interval_exp < SECTOR_SHIFT ||
		   bi->interval_exp > ilog2(lim->logical_block_size)) {
		pr_warn("invalid interval_exp %u\n", bi->interval_exp);
		return -EINVAL;
	}

	/*
	 * Some IO controllers can not handle data intervals straddling
	 * multiple bio_vecs.  For those, enforce alignment so that those are
	 * never generated, and that each buffer is aligned as expected.
	 */
	if (!(bi->flags & BLK_SPLIT_INTERVAL_CAPABLE) && bi->csum_type) {
		lim->dma_alignment = max(lim->dma_alignment,
					(1U << bi->interval_exp) - 1);
	}

	/*
	 * The block layer automatically adds integrity data for bios that don't
	 * already have it.  Limit the I/O size so that a single maximum size
	 * metadata segment can cover the integrity data for the entire I/O.
	 */
	lim->max_sectors = min(lim->max_sectors,
		max_integrity_io_size(lim) >> SECTOR_SHIFT);

	return 0;
}

/*
 * Returns max guaranteed bytes which we can fit in a bio.
 *
 * We request that an atomic_write is ITER_UBUF iov_iter (so a single vector),
 * so we assume that we can fit in at least PAGE_SIZE in a segment, apart from
 * the first and last segments.
 */
static unsigned int blk_queue_max_guaranteed_bio(struct queue_limits *lim)
{
	unsigned int max_segments = min(BIO_MAX_VECS, lim->max_segments);
	unsigned int length;

	length = min(max_segments, 2) * lim->logical_block_size;
	if (max_segments > 2)
		length += (max_segments - 2) * PAGE_SIZE;

	return length;
}

static void blk_atomic_writes_update_limits(struct queue_limits *lim)
{
	unsigned int unit_limit = min(lim->max_hw_sectors << SECTOR_SHIFT,
					blk_queue_max_guaranteed_bio(lim));

	unit_limit = rounddown_pow_of_two(unit_limit);

	lim->atomic_write_max_sectors =
		min(lim->atomic_write_hw_max >> SECTOR_SHIFT,
			lim->max_hw_sectors);
	lim->atomic_write_unit_min =
		min(lim->atomic_write_hw_unit_min, unit_limit);
	lim->atomic_write_unit_max =
		min(lim->atomic_write_hw_unit_max, unit_limit);
	lim->atomic_write_boundary_sectors =
		lim->atomic_write_hw_boundary >> SECTOR_SHIFT;
}

Annotation

Implementation Notes