Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb8b2848 authored by Jonathan Brassow's avatar Jonathan Brassow Committed by Alasdair G Kergon
Browse files

dm log: auto load modules



If the log type is not recognised, attempt to load the module
'dm-log-<type>.ko'.

Signed-off-by: default avatarJonathan Brassow <jbrassow@redhat.com>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
parent 304f3f6a
Loading
Loading
Loading
Loading
+50 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ int dm_unregister_dirty_log_type(struct dirty_log_type *type)
	return 0;
}

static struct dirty_log_type *get_type(const char *type_name)
static struct dirty_log_type *_get_type(const char *type_name)
{
	struct dirty_log_type *type;

@@ -61,6 +61,55 @@ static struct dirty_log_type *get_type(const char *type_name)
	return NULL;
}

/*
 * get_type
 * @type_name
 *
 * Attempt to retrieve the dirty_log_type by name.  If not already
 * available, attempt to load the appropriate module.
 *
 * Log modules are named "dm-log-" followed by the 'type_name'.
 * Modules may contain multiple types.
 * This function will first try the module "dm-log-<type_name>",
 * then truncate 'type_name' on the last '-' and try again.
 *
 * For example, if type_name was "clustered-disk", it would search
 * 'dm-log-clustered-disk' then 'dm-log-clustered'.
 *
 * Returns: dirty_log_type* on success, NULL on failure
 */
static struct dirty_log_type *get_type(const char *type_name)
{
	char *p, *type_name_dup;
	struct dirty_log_type *type;

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

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

	while (request_module("dm-log-%s", type_name_dup) ||
	       !(type = _get_type(type_name))) {
		p = strrchr(type_name_dup, '-');
		if (!p)
			break;
		p[0] = '\0';
	}

	if (!type)
		DMWARN("Module for logging type \"%s\" not found.", type_name);

	kfree(type_name_dup);

	return type;
}

static void put_type(struct dirty_log_type *type)
{
	spin_lock(&_lock);