drivers/md/dm-vdo/vio.c

Source file repositories/reference/linux-study-clean/drivers/md/dm-vdo/vio.c

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-vdo/vio.c
Extension
.c
Size
13989 bytes
Lines
513
Domain
Driver Families
Bucket
drivers/md
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct vio_pool {
	/* The number of objects managed by the pool */
	size_t size;
	/* The list of objects which are available */
	struct list_head available;
	/* The queue of requestors waiting for objects from the pool */
	struct vdo_wait_queue waiting;
	/* The number of objects currently in use */
	size_t busy_count;
	/* The list of objects which are in use */
	struct list_head busy;
	/* The ID of the thread on which this pool may be used */
	thread_id_t thread_id;
	/* The buffer backing the pool's vios */
	char *buffer;
	/* The pool entries */
	struct pooled_vio vios[];
};

physical_block_number_t pbn_from_vio_bio(struct bio *bio)
{
	struct vio *vio = bio->bi_private;
	struct vdo *vdo = vio->completion.vdo;
	physical_block_number_t pbn = bio->bi_iter.bi_sector / VDO_SECTORS_PER_BLOCK;

	return ((pbn == VDO_GEOMETRY_BLOCK_LOCATION) ? pbn : pbn + vdo->geometry.bio_offset);
}

static int create_multi_block_bio(block_count_t size, struct bio **bio_ptr)
{
	struct bio *bio = NULL;
	int result;

	result = vdo_allocate_memory(sizeof(struct bio) + sizeof(struct bio_vec) * (size + 1),
				     __alignof__(struct bio), "bio", &bio);
	if (result != VDO_SUCCESS)
		return result;

	*bio_ptr = bio;
	return VDO_SUCCESS;
}

int vdo_create_bio(struct bio **bio_ptr)
{
	return create_multi_block_bio(1, bio_ptr);
}

void vdo_free_bio(struct bio *bio)
{
	if (bio == NULL)
		return;

	bio_uninit(bio);
	vdo_free(vdo_forget(bio));
}

int allocate_vio_components(struct vdo *vdo, enum vio_type vio_type,
			    enum vio_priority priority, void *parent,
			    unsigned int block_count, char *data, struct vio *vio)
{
	struct bio *bio;
	int result;

	result = VDO_ASSERT(block_count <= MAX_BLOCKS_PER_VIO,
			    "block count %u does not exceed maximum %u", block_count,
			    MAX_BLOCKS_PER_VIO);
	if (result != VDO_SUCCESS)
		return result;

	result = VDO_ASSERT(((vio_type != VIO_TYPE_UNINITIALIZED) && (vio_type != VIO_TYPE_DATA)),
			    "%d is a metadata type", vio_type);
	if (result != VDO_SUCCESS)
		return result;

	result = create_multi_block_bio(block_count, &bio);
	if (result != VDO_SUCCESS)
		return result;

	initialize_vio(vio, bio, block_count, vio_type, priority, vdo);
	vio->completion.parent = parent;
	vio->data = data;
	return VDO_SUCCESS;
}

/**
 * create_multi_block_metadata_vio() - Create a vio.
 * @vdo: The vdo on which the vio will operate.
 * @vio_type: The type of vio to create.
 * @priority: The relative priority to assign to the vio.
 * @parent: The parent of the vio.

Annotation

Implementation Notes