drivers/md/dm-exception-store.c

Source file repositories/reference/linux-study-clean/drivers/md/dm-exception-store.c

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-exception-store.c
Extension
.c
Size
6606 bytes
Lines
292
Domain
Driver Families
Bucket
drivers/md
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
 * Copyright (C) 2006-2008 Red Hat GmbH
 *
 * This file is released under the GPL.
 */

#include "dm-exception-store.h"

#include <linux/ctype.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/slab.h>

#define DM_MSG_PREFIX "snapshot exception stores"

static LIST_HEAD(_exception_store_types);
static DEFINE_SPINLOCK(_lock);

static struct dm_exception_store_type *__find_exception_store_type(const char *name)
{
	struct dm_exception_store_type *type;

	list_for_each_entry(type, &_exception_store_types, list)
		if (!strcmp(name, type->name))
			return type;

	return NULL;
}

static struct dm_exception_store_type *_get_exception_store_type(const char *name)
{
	struct dm_exception_store_type *type;

	spin_lock(&_lock);

	type = __find_exception_store_type(name);

	if (type && !try_module_get(type->module))
		type = NULL;

	spin_unlock(&_lock);

	return type;
}

/*
 * get_type
 * @type_name
 *
 * Attempt to retrieve the dm_exception_store_type by name.  If not already
 * available, attempt to load the appropriate module.
 *
 * Exstore modules are named "dm-exstore-" followed by the 'type_name'.
 * Modules may contain multiple types.
 * This function will first try the module "dm-exstore-<type_name>",
 * then truncate 'type_name' on the last '-' and try again.
 *
 * For example, if type_name was "clustered-shared", it would search
 * 'dm-exstore-clustered-shared' then 'dm-exstore-clustered'.
 *
 * 'dm-exception-store-<type_name>' is too long of a name in my
 * opinion, which is why I've chosen to have the files
 * containing exception store implementations be 'dm-exstore-<type_name>'.
 * If you want your module to be autoloaded, you will follow this
 * naming convention.
 *
 * Returns: dm_exception_store_type* on success, NULL on failure
 */
static struct dm_exception_store_type *get_type(const char *type_name)
{
	char *p, *type_name_dup;
	struct dm_exception_store_type *type;

	type = _get_exception_store_type(type_name);
	if (type)
		return type;

	type_name_dup = kstrdup(type_name, GFP_KERNEL);
	if (!type_name_dup) {
		DMERR("No memory left to attempt load for \"%s\"", type_name);
		return NULL;
	}

	while (request_module("dm-exstore-%s", type_name_dup) ||
	       !(type = _get_exception_store_type(type_name))) {
		p = strrchr(type_name_dup, '-');

Annotation

Implementation Notes