diff options
author | Jonathan Brassow <jbrassow@redhat.com> | 2008-02-07 21:11:19 -0500 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2008-02-07 21:11:19 -0500 |
commit | fb8b284806124bef250196007d7373ea3fe26194 (patch) | |
tree | 8e34cc38a2c5a0e8e7a937c53421cf7f76466a00 /drivers | |
parent | 304f3f6a58301316da612d7bf21d9abe1369d456 (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')
-rw-r--r-- | drivers/md/dm-log.c | 51 |
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 | ||
44 | static struct dirty_log_type *get_type(const char *type_name) | 44 | static 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 | */ | ||
81 | static 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 | |||
64 | static void put_type(struct dirty_log_type *type) | 113 | static void put_type(struct dirty_log_type *type) |
65 | { | 114 | { |
66 | spin_lock(&_lock); | 115 | spin_lock(&_lock); |