drivers/md/dm-vdo/indexer/io-factory.c

Source file repositories/reference/linux-study-clean/drivers/md/dm-vdo/indexer/io-factory.c

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-vdo/indexer/io-factory.c
Extension
.c
Size
10022 bytes
Lines
416
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 io_factory {
	struct block_device *bdev;
	atomic_t ref_count;
};

/* The buffered reader allows efficient I/O by reading page-sized segments into a buffer. */
struct buffered_reader {
	struct io_factory *factory;
	struct dm_bufio_client *client;
	struct dm_buffer *buffer;
	sector_t limit;
	sector_t block_number;
	u8 *start;
	u8 *end;
};

#define MAX_READ_AHEAD_BLOCKS 4

/*
 * The buffered writer allows efficient I/O by buffering writes and committing page-sized segments
 * to storage.
 */
struct buffered_writer {
	struct io_factory *factory;
	struct dm_bufio_client *client;
	struct dm_buffer *buffer;
	sector_t limit;
	sector_t block_number;
	u8 *start;
	u8 *end;
	int error;
};

static void uds_get_io_factory(struct io_factory *factory)
{
	atomic_inc(&factory->ref_count);
}

int uds_make_io_factory(struct block_device *bdev, struct io_factory **factory_ptr)
{
	int result;
	struct io_factory *factory;

	result = vdo_allocate(1, __func__, &factory);
	if (result != VDO_SUCCESS)
		return result;

	factory->bdev = bdev;
	atomic_set_release(&factory->ref_count, 1);

	*factory_ptr = factory;
	return UDS_SUCCESS;
}

int uds_replace_storage(struct io_factory *factory, struct block_device *bdev)
{
	factory->bdev = bdev;
	return UDS_SUCCESS;
}

/* Free an I/O factory once all references have been released. */
void uds_put_io_factory(struct io_factory *factory)
{
	if (atomic_add_return(-1, &factory->ref_count) <= 0)
		vdo_free(factory);
}

size_t uds_get_writable_size(struct io_factory *factory)
{
	return bdev_nr_bytes(factory->bdev);
}

/* Create a struct dm_bufio_client for an index region starting at offset. */
int uds_make_bufio(struct io_factory *factory, off_t block_offset, size_t block_size,
		   unsigned int reserved_buffers, struct dm_bufio_client **client_ptr)
{
	struct dm_bufio_client *client;

	client = dm_bufio_client_create(factory->bdev, block_size, reserved_buffers, 0,
					NULL, NULL, 0);
	if (IS_ERR(client))
		return -PTR_ERR(client);

	dm_bufio_set_sector_offset(client, block_offset * SECTORS_PER_BLOCK);
	*client_ptr = client;
	return UDS_SUCCESS;
}

static void read_ahead(struct buffered_reader *reader, sector_t block_number)
{

Annotation

Implementation Notes