2 * TUX - Integrated Application Protocols Layer and Object Cache
4 * Copyright (C) 2000, 2001, Ingo Molnar <mingo@redhat.com>
6 * mod.c: loading/registering of dynamic TUX modules
10 #include <linux/kmod.h>
12 /****************************************************************
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 ****************************************************************/
29 DEFINE_SPINLOCK(tuxmodules_lock);
30 static LIST_HEAD(tuxmodules_list);
32 tcapi_template_t * get_first_usermodule (void)
34 tcapi_template_t *tcapi;
35 struct list_head *head, *curr, *next;
37 spin_lock(&tuxmodules_lock);
38 head = &tuxmodules_list;
41 while ((curr = next) != head) {
42 tcapi = list_entry(curr, tcapi_template_t, modules);
44 if (tcapi->userspace_id) {
45 spin_unlock(&tuxmodules_lock);
49 spin_unlock(&tuxmodules_lock);
53 static tcapi_template_t * lookup_module (const char *vfs_name)
55 tcapi_template_t *tcapi;
56 struct list_head *head, *curr, *next;
58 while (*vfs_name == '/')
60 Dprintk("looking up TUX module {%s}.\n", vfs_name);
61 head = &tuxmodules_list;
64 while ((curr = next) != head) {
65 tcapi = list_entry(curr, tcapi_template_t, modules);
67 Dprintk("checking module {%s} == {%s}?\n", vfs_name, tcapi->vfs_name);
68 if (!strcmp(tcapi->vfs_name, vfs_name))
75 * Attempt to load a TUX application module.
76 * This is the slow path, we cache ('link') the module's
77 * API vector to the inode.
78 * The module loading path is serialized, and we handshake
79 * with the loaded module and fetch its API vector.
81 tcapi_template_t * lookup_tuxmodule (const char *filename)
83 tcapi_template_t *tcapi;
85 spin_lock(&tuxmodules_lock);
86 tcapi = lookup_module(filename);
88 Dprintk("did not find module vfs:{%s}\n", filename);
89 spin_unlock(&tuxmodules_lock);
94 int register_tuxmodule (tcapi_template_t *tcapi)
98 spin_lock(&tuxmodules_lock);
100 if (lookup_module(tcapi->vfs_name)) {
101 Dprintk("module with VFS binding '%s' already registered!\n",
106 list_add(&tcapi->modules, &tuxmodules_list);
108 Dprintk("TUX module %s registered.\n", tcapi->vfs_name);
110 spin_unlock(&tuxmodules_lock);
115 void unregister_all_tuxmodules (void)
117 tcapi_template_t *tcapi;
118 struct list_head *curr;
120 spin_lock(&tuxmodules_lock);
121 while (((curr = tuxmodules_list.next)) != &tuxmodules_list) {
122 tcapi = list_entry(curr, tcapi_template_t, modules);
124 kfree(tcapi->vfs_name);
127 spin_unlock(&tuxmodules_lock);
130 tcapi_template_t * unregister_tuxmodule (char *vfs_name)
132 tcapi_template_t *tcapi;
135 spin_lock(&tuxmodules_lock);
136 tcapi = lookup_module(vfs_name);
138 Dprintk("huh, module %s not registered??\n", vfs_name);
141 list_del(&tcapi->modules);
142 Dprintk("TUX module %s unregistered.\n", vfs_name);
144 spin_unlock(&tuxmodules_lock);
149 static int check_module_version (user_req_t *u_info)
151 int major, minor, patch, ret;
153 ret = copy_from_user(&major, &u_info->version_major, sizeof(int));
154 ret += copy_from_user(&minor, &u_info->version_minor, sizeof(int));
155 ret += copy_from_user(&patch, &u_info->version_patch, sizeof(int));
159 if ((major != TUX_MAJOR_VERSION) || (minor > TUX_MINOR_VERSION)) {
161 printk(KERN_ERR "TUX: module version %d:%d incompatible with kernel version %d:%d!\n", major, minor, TUX_MAJOR_VERSION, TUX_MINOR_VERSION);
167 int user_register_module (user_req_t *u_info)
170 tcapi_template_t *tcapi;
171 char modulename [MAX_URI_LEN+1];
173 ret = check_module_version(u_info);
178 * Check module name length.
180 ret = strnlen_user(u_info->objectname, MAX_URI_LEN+2);
184 if (ret >= MAX_URI_LEN)
187 Dprintk("register user-module, %p.\n", u_info);
188 ret = strncpy_from_user(modulename, u_info->objectname, MAX_URI_LEN);
192 Dprintk("... user-module is: {%s}.\n", modulename);
193 len = strlen(modulename);
195 printk(KERN_ERR "no module name provided: please upgrade your TUX user-space utilities!\n");
196 if (!len || (len > MAX_URI_LEN))
198 Dprintk("... user-module len is: %d.\n", len);
200 ret = copy_from_user(&idx, &u_info->module_index, sizeof(int));
203 Dprintk("... user-module index is: %d.\n", idx);
206 tcapi = (tcapi_template_t *) kmalloc(sizeof(*tcapi), GFP_KERNEL);
209 memset(tcapi, 0, sizeof(*tcapi));
211 tcapi->vfs_name = (char *) kmalloc(len+1, GFP_KERNEL);
212 if (!tcapi->vfs_name) {
216 strcpy(tcapi->vfs_name, modulename);
217 tcapi->userspace_id = idx;
219 Dprintk("... registering module {%s}.\n", tcapi->vfs_name);
220 ret = register_tuxmodule(tcapi);
225 int user_unregister_module (user_req_t *u_info)
228 tcapi_template_t *tcapi;
229 char modulename [MAX_URI_LEN+1];
232 * Check module name length.
234 ret = strnlen_user(u_info->objectname, MAX_URI_LEN+2);
238 if (ret >= MAX_URI_LEN)
240 Dprintk("unregister user-module, %p.\n", u_info);
241 ret = strncpy_from_user(modulename, u_info->objectname, MAX_URI_LEN);
245 Dprintk("... user-module is: {%s}.\n", modulename);
246 len = strlen(modulename);
247 if (!len || (len > MAX_URI_LEN))
249 Dprintk("... user-module len is: %d.\n", len);
251 Dprintk("... unregistering module {%s}.\n", modulename);
252 tcapi = unregister_tuxmodule(modulename);
256 kfree(tcapi->vfs_name);