1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * An implementation of a loadable kernel mode driver providing
5 * multiple kernel/user space bidirectional communications links.
7 * Author: Alan Cox <alan@cymru.net>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
13 * Adapted to become the Linux 2.0 Coda pseudo device
14 * Peter Braam <braam@maths.ox.ac.uk>
15 * Michael Callahan <mjc@emmy.smith.edu>
17 * Changes for Linux 2.1
18 * Copyright (c) 1997 Carnegie-Mellon University
20 * Redone again for Intermezzo
21 * Copyright (c) 1998 Peter J. Braam
23 * Hacked up again for simulated OBD
24 * Copyright (c) 1999 Stelias Computing, Inc.
25 * (authors {pschwan,braam}@stelias.com)
26 * Copyright (C) 1999 Seagate Technology, Inc.
27 * Copyright (C) 2001 Cluster File Systems, Inc.
33 #include <linux/config.h> /* for CONFIG_PROC_FS */
34 #include <linux/module.h>
35 #include <linux/errno.h>
36 #include <linux/kernel.h>
37 #include <linux/major.h>
38 #include <linux/kmod.h> /* for request_module() */
39 #include <linux/sched.h>
41 #include <linux/slab.h>
42 #include <linux/ioport.h>
43 #include <linux/fcntl.h>
44 #include <linux/delay.h>
45 #include <linux/skbuff.h>
46 #include <linux/proc_fs.h>
48 #include <linux/poll.h>
49 #include <linux/init.h>
50 #include <linux/list.h>
52 #include <asm/system.h>
54 #include <asm/uaccess.h>
55 #include <linux/miscdevice.h>
57 #define DEBUG_SUBSYSTEM S_CLASS
59 #include <linux/obd_support.h>
60 #include <linux/obd_class.h>
62 static int obd_init_magic;
63 unsigned long obd_memory = 0;
64 unsigned long obd_fail_loc = 0;
65 struct obd_device obd_dev[MAX_OBD_DEVICES];
66 struct list_head obd_types;
68 /* opening /dev/obd */
69 static int obd_class_open(struct inode * inode, struct file * file)
73 file->private_data = NULL;
78 /* closing /dev/obd */
79 static int obd_class_release(struct inode * inode, struct file * file)
83 if (file->private_data)
84 file->private_data = NULL;
90 static int obd_class_name2dev(char *name)
95 for (i=0; i < MAX_OBD_DEVICES; i++) {
96 struct obd_device *obd = &obd_dev[i];
97 if (obd->obd_name && strcmp(name, obd->obd_name) == 0) {
107 * support functions: we could use inter-module communication, but this
108 * is more portable to other OS's
110 static struct obd_type *obd_search_type(char *nm)
112 struct list_head *tmp;
113 struct obd_type *type;
114 CDEBUG(D_INFO, "SEARCH %s\n", nm);
117 while ( (tmp = tmp->next) != &obd_types ) {
118 type = list_entry(tmp, struct obd_type, typ_chain);
119 CDEBUG(D_INFO, "TYP %s\n", type->typ_name);
120 if (strlen(type->typ_name) == strlen(nm) &&
121 strcmp(type->typ_name, nm) == 0 ) {
128 static struct obd_type *obd_nm_to_type(char *nm)
130 struct obd_type *type = obd_search_type(nm);
134 if ( !request_module(nm) ) {
135 CDEBUG(D_INFO, "Loaded module '%s'\n", nm);
136 type = obd_search_type(nm);
138 CDEBUG(D_INFO, "Can't load module '%s'\n", nm);
145 /* to control /dev/obd */
146 static int obd_class_ioctl (struct inode * inode, struct file * filp,
147 unsigned int cmd, unsigned long arg)
149 /* NOTE this must be larger than any of the ioctl data structs */
151 struct obd_ioctl_data *data;
152 struct obd_device *obd = filp->private_data;
153 struct obd_conn conn;
154 int rw = OBD_BRW_READ;
158 memset(buf, 0, sizeof(buf));
160 if (!obd && cmd != OBD_IOC_DEVICE && cmd != TCGETS
161 && cmd != OBD_IOC_NAME2DEV) {
162 CERROR("OBD ioctl: No device\n");
165 if (obd_ioctl_getdata(buf, buf + 800, (void *)arg)) {
166 CERROR("OBD ioctl: data error\n");
169 data = (struct obd_ioctl_data *)buf;
174 case OBD_IOC_DEVICE: {
175 CDEBUG(D_IOCTL, "\n");
176 if (data->ioc_dev >= MAX_OBD_DEVICES || data->ioc_dev < 0) {
177 CERROR("OBD ioctl: DEVICE insufficient devices\n");
180 CDEBUG(D_IOCTL, "device %d\n", data->ioc_dev);
182 filp->private_data = &obd_dev[data->ioc_dev];
186 case OBD_IOC_NAME2DEV: {
189 filp->private_data = NULL;
191 if (!data->ioc_inlbuf1) {
192 CERROR("No name passed!\n");
195 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
196 dev = obd_class_name2dev(data->ioc_inlbuf1);
199 CERROR("No device for name %s!\n", data->ioc_inlbuf1);
203 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
205 filp->private_data = &obd_dev[data->ioc_dev];
206 err = copy_to_user((int *)arg, data, sizeof(*data));
210 case OBD_IOC_ATTACH: {
211 struct obd_type *type;
213 /* have we attached a type to this device */
214 if (obd->obd_flags & OBD_ATTACHED) {
215 CERROR("OBD: Device %d already typed as %s.\n",
216 obd->obd_minor, MKSTR(obd->obd_type->typ_name));
220 CDEBUG(D_IOCTL, "attach %s %s\n", MKSTR(data->ioc_inlbuf1),
221 MKSTR(data->ioc_inlbuf2));
224 type = obd_nm_to_type(data->ioc_inlbuf1);
226 CERROR("OBD: unknown type dev %d\n", obd->obd_minor);
230 obd->obd_type = type;
231 obd->obd_multi_count = 0;
232 INIT_LIST_HEAD(&obd->obd_gen_clients);
233 INIT_LIST_HEAD(&obd->obd_req_list);
236 if (OBT(obd) && OBP(obd, attach))
237 err = OBP(obd,attach)(obd, sizeof(*data), data);
239 obd->obd_type = NULL;
241 obd->obd_flags |= OBD_ATTACHED;
243 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
244 obd->obd_minor, data->ioc_inlbuf1);
245 obd->obd_proc_entry =
246 proc_lustre_register_obd_device(obd);
247 if (data->ioc_inlbuf2) {
248 int len = strlen(data->ioc_inlbuf2);
249 OBD_ALLOC(obd->obd_name, len + 1);
250 if (!obd->obd_name) {
251 CERROR("no memory\n");
254 memcpy(obd->obd_name, data->ioc_inlbuf2, len+1);
263 case OBD_IOC_DETACH: {
265 if (obd->obd_flags & OBD_SET_UP) {
266 CERROR("OBD device %d still set up\n", obd->obd_minor);
269 if (! (obd->obd_flags & OBD_ATTACHED) ) {
270 CERROR("OBD device %d not attached\n", obd->obd_minor);
273 if ( !list_empty(&obd->obd_gen_clients) ) {
274 CERROR("OBD device %d has connected clients\n",
278 if ( !list_empty(&obd->obd_req_list) ) {
279 CERROR("OBD device %d has hanging requests\n",
285 OBD_FREE(obd->obd_name, strlen(obd->obd_name)+ 1);
286 obd->obd_name = NULL;
289 if (obd->obd_proc_entry)
290 proc_lustre_release_obd_device(obd);
292 obd->obd_flags &= ~OBD_ATTACHED;
293 obd->obd_type->typ_refcnt--;
294 obd->obd_type = NULL;
299 case OBD_IOC_SETUP: {
300 /* have we attached a type to this device? */
301 if (!(obd->obd_flags & OBD_ATTACHED)) {
302 CERROR("Device %d not attached\n", obd->obd_minor);
306 /* has this been done already? */
307 if ( obd->obd_flags & OBD_SET_UP ) {
308 CERROR("Device %d already setup (type %s)\n",
309 obd->obd_minor, obd->obd_type->typ_name);
313 if ( OBT(obd) && OBP(obd, setup) )
314 err = obd_setup(obd, sizeof(*data), data);
317 obd->obd_type->typ_refcnt++;
318 obd->obd_flags |= OBD_SET_UP;
323 case OBD_IOC_CLEANUP: {
324 /* have we attached a type to this device? */
325 if (!(obd->obd_flags & OBD_ATTACHED)) {
326 CERROR("Device %d not attached\n", obd->obd_minor);
330 if ( OBT(obd) && OBP(obd, cleanup) )
331 err = obd_cleanup(obd);
334 obd->obd_flags &= ~OBD_SET_UP;
335 obd->obd_type->typ_refcnt--;
340 case OBD_IOC_CONNECT: {
341 conn.oc_id = data->ioc_conn1;
344 err = obd_connect(&conn);
346 CDEBUG(D_IOCTL, "assigned connection %d\n", conn.oc_id);
347 data->ioc_conn1 = conn.oc_id;
351 err = copy_to_user((int *)arg, data, sizeof(*data));
355 case OBD_IOC_DISCONNECT: {
356 conn.oc_id = data->ioc_conn1;
359 err = obd_disconnect(&conn);
363 case OBD_IOC_DEC_USE_COUNT: {
368 case OBD_IOC_CREATE: {
369 conn.oc_id = data->ioc_conn1;
372 err = obd_create(&conn, &data->ioc_obdo1);
376 err = copy_to_user((int *)arg, data, sizeof(*data));
380 case OBD_IOC_GETATTR: {
381 conn.oc_id = data->ioc_conn1;
384 err = obd_getattr(&conn, &data->ioc_obdo1);
388 err = copy_to_user((int *)arg, data, sizeof(*data));
392 case OBD_IOC_SETATTR: {
393 conn.oc_id = data->ioc_conn1;
396 err = obd_setattr(&conn, &data->ioc_obdo1);
400 err = copy_to_user((int *)arg, data, sizeof(*data));
404 case OBD_IOC_DESTROY: {
405 conn.oc_id = data->ioc_conn1;
408 err = obd_destroy(&conn, &data->ioc_obdo1);
412 err = copy_to_user((int *)arg, data, sizeof(*data));
416 case OBD_IOC_BRW_WRITE:
418 case OBD_IOC_BRW_READ: {
419 /* FIXME: use a better ioctl data struct than obd_ioctl_data.
420 * We don't really support multiple-obdo I/Os here,
421 * for example offset and count are not per-obdo.
423 struct obd_conn conns[2];
424 struct obdo *obdos[2] = { NULL, NULL };
425 obd_count oa_bufs[2] = { 0, 0 };
426 struct page **bufs = NULL;
427 obd_size *counts = NULL;
428 obd_off *offsets = NULL;
429 obd_flag *flags = NULL;
434 pages = oa_bufs[0] = data->ioc_plen1 / PAGE_SIZE;
435 if (data->ioc_obdo2.o_id) {
437 oa_bufs[1] = data->ioc_plen2 / PAGE_SIZE;
441 CDEBUG(D_INODE, "BRW %s with %dx%d pages\n",
442 rw == OBD_BRW_READ ? "read" : "write",
444 bufs = kmalloc(pages * sizeof(*bufs), GFP_KERNEL);
445 counts = kmalloc(pages * sizeof(*counts), GFP_KERNEL);
446 offsets = kmalloc(pages * sizeof(*offsets), GFP_KERNEL);
447 flags = kmalloc(pages * sizeof(*flags), GFP_KERNEL);
448 if (!bufs || !counts || !offsets || !flags) {
449 CERROR("no memory for %d BRW per-page data\n", pages);
454 obdos[0] = &data->ioc_obdo1;
456 obdos[1] = &data->ioc_obdo2;
458 for (i = 0, pages = 0; i < num; i++) {
462 conns[i].oc_id = (&data->ioc_conn1)[i];
463 conns[i].oc_dev = obd;
465 from = (&data->ioc_pbuf1)[i];
466 off = data->ioc_offset;
468 for (j = 0; j < oa_bufs[i];
469 j++, pages++, off += PAGE_SIZE, from += PAGE_SIZE){
472 to = __get_free_pages(GFP_KERNEL, 0);
475 copy_from_user((void *)to,from,PAGE_SIZE))
478 CERROR("no memory for brw pages\n");
480 GOTO(brw_cleanup, err);
482 bufs[pages] = virt_to_page(to);
483 counts[pages] = PAGE_SIZE;
484 offsets[pages] = off;
489 err = obd_brw(rw, conns, num, obdos, oa_bufs, bufs,
490 counts, offsets, flags);
495 free_pages((unsigned long)page_address(bufs[pages]), 0);
504 conn.oc_id = data->ioc_conn1;
507 err = obd_iocontrol(cmd, &conn, sizeof(*data), data, NULL);
511 err = copy_to_user((int *)arg, data, sizeof(*data));
515 } /* obd_class_ioctl */
518 /* Driver interface done, utility functions follow */
519 int obd_register_type(struct obd_ops *ops, char *nm)
521 struct obd_type *type;
525 if (obd_init_magic != 0x11223344) {
526 CERROR("bad magic for type\n");
530 if ( obd_nm_to_type(nm) ) {
531 CDEBUG(D_IOCTL, "Type %s already registered\n", nm);
535 OBD_ALLOC(type, sizeof(*type));
538 INIT_LIST_HEAD(&type->typ_chain);
540 list_add(&type->typ_chain, obd_types.next);
546 int obd_unregister_type(char *nm)
548 struct obd_type *type = obd_nm_to_type(nm);
554 CERROR("unknown obd type\n");
558 if ( type->typ_refcnt ) {
560 CERROR("type %s has refcount (%d)\n", nm, type->typ_refcnt);
564 list_del(&type->typ_chain);
565 OBD_FREE(type, sizeof(*type));
568 } /* obd_unregister_type */
570 /* declare character device */
571 static struct file_operations obd_psdev_fops = {
572 ioctl: obd_class_ioctl, /* ioctl */
573 open: obd_class_open, /* open */
574 release: obd_class_release, /* release */
578 #define OBD_MINOR 241
579 static struct miscdevice obd_psdev = {
585 EXPORT_SYMBOL(obd_register_type);
586 EXPORT_SYMBOL(obd_unregister_type);
588 EXPORT_SYMBOL(obd_dev);
590 EXPORT_SYMBOL(gen_connect);
591 EXPORT_SYMBOL(gen_client);
592 EXPORT_SYMBOL(gen_cleanup);
593 EXPORT_SYMBOL(gen_disconnect);
594 EXPORT_SYMBOL(gen_copy_data);
595 EXPORT_SYMBOL(obdo_cachep);
597 /* EXPORT_SYMBOL(gen_multi_attach); */
598 EXPORT_SYMBOL(gen_multi_setup);
599 EXPORT_SYMBOL(gen_multi_cleanup);
600 EXPORT_SYMBOL(obd_memory);
601 EXPORT_SYMBOL(obd_fail_loc);
603 static int __init init_obdclass(void)
608 printk(KERN_INFO "OBD class driver v0.01, braam@stelias.com\n");
610 INIT_LIST_HEAD(&obd_types);
612 if ((err = misc_register(&obd_psdev))) {
613 CERROR("cannot register %d err %d\n", OBD_MINOR, err);
617 for (i = 0; i < MAX_OBD_DEVICES; i++) {
618 memset(&(obd_dev[i]), 0, sizeof(obd_dev[i]));
619 obd_dev[i].obd_minor = i;
620 INIT_LIST_HEAD(&obd_dev[i].obd_gen_clients);
621 INIT_LIST_HEAD(&obd_dev[i].obd_req_list);
622 init_waitqueue_head(&obd_dev[i].obd_req_waitq);
625 err = obd_init_obdo_cache();
629 obd_init_magic = 0x11223344;
633 static void __exit cleanup_obdclass(void)
638 misc_deregister(&obd_psdev);
639 for (i = 0; i < MAX_OBD_DEVICES; i++) {
640 struct obd_device *obd = &obd_dev[i];
641 if ( obd->obd_type &&
642 (obd->obd_flags & OBD_SET_UP) &&
643 OBT(obd) && OBP(obd, detach) ) {
644 /* XXX should this call generic detach otherwise? */
645 OBP(obd, detach)(obd);
649 obd_cleanup_obdo_cache();
651 CERROR("obd memory leaked: %ld bytes\n", obd_memory);
656 MODULE_AUTHOR("Cluster File Systems, Inc. <braam@clusterfs.com>");
657 MODULE_DESCRIPTION("Lustre Class Driver v1.0");
658 MODULE_LICENSE("GPL");
660 module_init(init_obdclass);
661 module_exit(cleanup_obdclass);