Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1725

kernel-2.6.18-238.el5.src.rpm

From: Jonathan Brassow <jbrassow@redhat.com>
Date: Fri, 11 Jan 2008 11:05:58 -0600
Subject: [md] dm: auto loading of dm-mirror log modules
Message-id: 1200071158.27562.5.camel@hydrogen
O-Subject: Re: [RHEL 5.2 PATCH] auto loading of dm-mirror log modules
Bugzilla: 388661

Bug #388661

This patch will attempt to load a logging module if logging type is not
already available.  This action is performed in a generic way by
appending the logging type name after 'dm-log-'.  The logging modules
must then be named 'dm-log-<type>.ko'.

 brassow

Acked-by: Alasdair G Kergon <agk@redhat.com>

diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 9059df7..148e11c 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -42,7 +42,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;
 
@@ -62,6 +62,62 @@ 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 immediately available, attempt to find
+ * the appropriate module.
+ *
+ * Log modules are named "dm-log-" followed by
+ * the 'type_name'.  Some modules contain multiple
+ * types, however.  In those cases, the 'type_name'
+ * may include more than we need.  However, '-'s
+ * in the type_name reveal the extra information.
+ * So, this function will try loading the module
+ * "dm-log-<type_name>", then try truncating the
+ * 'type_name' on the last '-' and try again.
+ * For example, if type_name was "clustered-disk",
+ * it would try loading:
+ *   dm-log-clustered-disk
+ *   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))) {
+		/* find the last '-' */
+		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);