aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorJonathan Brassow <jbrassow@redhat.com>2008-02-07 21:11:19 -0500
committerAlasdair G Kergon <agk@redhat.com>2008-02-07 21:11:19 -0500
commitfb8b284806124bef250196007d7373ea3fe26194 (patch)
tree8e34cc38a2c5a0e8e7a937c53421cf7f76466a00 /drivers/md
parent304f3f6a58301316da612d7bf21d9abe1369d456 (diff)
dm log: auto load modules
If the log type is not recognised, attempt to load the module 'dm-log-<type>.ko'. Signed-off-by: Jonathan Brassow <jbrassow@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-log.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 072ee4353eab..2a74b2142f50 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -41,7 +41,7 @@ int dm_unregister_dirty_log_type(struct dirty_log_type *type)
41 return 0; 41 return 0;
42} 42}
43 43
44static struct dirty_log_type *get_type(const char *type_name) 44static struct dirty_log_type *_get_type(const char *type_name)
45{ 45{
46 struct dirty_log_type *type; 46 struct dirty_log_type *type;
47 47
@@ -61,6 +61,55 @@ static struct dirty_log_type *get_type(const char *type_name)
61 return NULL; 61 return NULL;
62} 62}
63 63
64/*
65 * get_type
66 * @type_name
67 *
68 * Attempt to retrieve the dirty_log_type by name. If not already
69 * available, attempt to load the appropriate module.
70 *
71 * Log modules are named "dm-log-" followed by the 'type_name'.
72 * Modules may contain multiple types.
73 * This function will first try the module "dm-log-<type_name>",
74 * then truncate 'type_name' on the last '-' and try again.
75 *
76 * For example, if type_name was "clustered-disk", it would search
77 * 'dm-log-clustered-disk' then 'dm-log-clustered'.
78 *
79 * Returns: dirty_log_type* on success, NULL on failure
80 */
81static struct dirty_log_type *get_type(const char *type_name)
82{
83 char *p, *type_name_dup;
84 struct dirty_log_type *type;
85
86 type = _get_type(type_name);
87 if (type)
88 return type;
89
90 type_name_dup = kstrdup(type_name, GFP_KERNEL);
91 if (!type_name_dup) {
92 DMWARN("No memory left to attempt log module load for \"%s\"",
93 type_name);
94 return NULL;
95 }
96
97 while (request_module("dm-log-%s", type_name_dup) ||
98 !(type = _get_type(type_name))) {
99 p = strrchr(type_name_dup, '-');
100 if (!p)
101 break;
102 p[0] = '\0';
103 }
104
105 if (!type)
106 DMWARN("Module for logging type \"%s\" not found.", type_name);
107
108 kfree(type_name_dup);
109
110 return type;
111}
112
64static void put_type(struct dirty_log_type *type) 113static void put_type(struct dirty_log_type *type)
65{ 114{
66 spin_lock(&_lock); 115 spin_lock(&_lock);