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 && cmd != OBD_IOC_NEWDEV) {
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: {
187 /* Resolve a device name. This does not change the
188 * currently selected device.
192 if (!data->ioc_inlbuf1) {
193 CERROR("No name passed!\n");
196 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
197 dev = obd_class_name2dev(data->ioc_inlbuf1);
200 CERROR("No device for name %s!\n", data->ioc_inlbuf1);
204 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
206 err = copy_to_user((int *)arg, data, sizeof(*data));
210 case OBD_IOC_NEWDEV: {
214 filp->private_data = NULL;
215 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
216 struct obd_device *obd = &obd_dev[i];
217 if (!obd->obd_type) {
218 filp->private_data = obd;
229 err = copy_to_user((int *)arg, data, sizeof(*data));
233 case OBD_IOC_ATTACH: {
234 struct obd_type *type;
236 /* have we attached a type to this device */
237 if (obd->obd_flags & OBD_ATTACHED) {
238 CERROR("OBD: Device %d already typed as %s.\n",
239 obd->obd_minor, MKSTR(obd->obd_type->typ_name));
243 CDEBUG(D_IOCTL, "attach %s %s\n", MKSTR(data->ioc_inlbuf1),
244 MKSTR(data->ioc_inlbuf2));
247 type = obd_nm_to_type(data->ioc_inlbuf1);
249 CERROR("OBD: unknown type dev %d\n", obd->obd_minor);
253 obd->obd_type = type;
254 obd->obd_multi_count = 0;
255 INIT_LIST_HEAD(&obd->obd_gen_clients);
256 INIT_LIST_HEAD(&obd->obd_req_list);
259 if (OBT(obd) && OBP(obd, attach))
260 err = OBP(obd,attach)(obd, sizeof(*data), data);
262 obd->obd_type = NULL;
264 obd->obd_flags |= OBD_ATTACHED;
266 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
267 obd->obd_minor, data->ioc_inlbuf1);
268 obd->obd_proc_entry =
269 proc_lustre_register_obd_device(obd);
270 if (data->ioc_inlbuf2) {
271 int len = strlen(data->ioc_inlbuf2);
272 OBD_ALLOC(obd->obd_name, len + 1);
273 if (!obd->obd_name) {
274 CERROR("no memory\n");
277 memcpy(obd->obd_name, data->ioc_inlbuf2, len+1);
286 case OBD_IOC_DETACH: {
288 if (obd->obd_flags & OBD_SET_UP) {
289 CERROR("OBD device %d still set up\n", obd->obd_minor);
292 if (! (obd->obd_flags & OBD_ATTACHED) ) {
293 CERROR("OBD device %d not attached\n", obd->obd_minor);
296 if ( !list_empty(&obd->obd_gen_clients) ) {
297 CERROR("OBD device %d has connected clients\n",
301 if ( !list_empty(&obd->obd_req_list) ) {
302 CERROR("OBD device %d has hanging requests\n",
308 OBD_FREE(obd->obd_name, strlen(obd->obd_name)+ 1);
309 obd->obd_name = NULL;
312 if (obd->obd_proc_entry)
313 proc_lustre_release_obd_device(obd);
315 obd->obd_flags &= ~OBD_ATTACHED;
316 obd->obd_type->typ_refcnt--;
317 obd->obd_type = NULL;
322 case OBD_IOC_SETUP: {
323 /* have we attached a type to this device? */
324 if (!(obd->obd_flags & OBD_ATTACHED)) {
325 CERROR("Device %d not attached\n", obd->obd_minor);
329 /* has this been done already? */
330 if ( obd->obd_flags & OBD_SET_UP ) {
331 CERROR("Device %d already setup (type %s)\n",
332 obd->obd_minor, obd->obd_type->typ_name);
336 if ( OBT(obd) && OBP(obd, setup) )
337 err = obd_setup(obd, sizeof(*data), data);
340 obd->obd_type->typ_refcnt++;
341 obd->obd_flags |= OBD_SET_UP;
346 case OBD_IOC_CLEANUP: {
347 /* have we attached a type to this device? */
348 if (!(obd->obd_flags & OBD_ATTACHED)) {
349 CERROR("Device %d not attached\n", obd->obd_minor);
353 if ( OBT(obd) && OBP(obd, cleanup) )
354 err = obd_cleanup(obd);
357 obd->obd_flags &= ~OBD_SET_UP;
358 obd->obd_type->typ_refcnt--;
363 case OBD_IOC_CONNECT: {
364 conn.oc_id = data->ioc_conn1;
367 err = obd_connect(&conn);
369 CDEBUG(D_IOCTL, "assigned connection %d\n", conn.oc_id);
370 data->ioc_conn1 = conn.oc_id;
374 err = copy_to_user((int *)arg, data, sizeof(*data));
378 case OBD_IOC_DISCONNECT: {
379 conn.oc_id = data->ioc_conn1;
382 err = obd_disconnect(&conn);
386 case OBD_IOC_DEC_USE_COUNT: {
391 case OBD_IOC_CREATE: {
392 conn.oc_id = data->ioc_conn1;
395 err = obd_create(&conn, &data->ioc_obdo1);
399 err = copy_to_user((int *)arg, data, sizeof(*data));
403 case OBD_IOC_GETATTR: {
404 conn.oc_id = data->ioc_conn1;
407 err = obd_getattr(&conn, &data->ioc_obdo1);
411 err = copy_to_user((int *)arg, data, sizeof(*data));
415 case OBD_IOC_SETATTR: {
416 conn.oc_id = data->ioc_conn1;
419 err = obd_setattr(&conn, &data->ioc_obdo1);
423 err = copy_to_user((int *)arg, data, sizeof(*data));
427 case OBD_IOC_DESTROY: {
428 conn.oc_id = data->ioc_conn1;
431 err = obd_destroy(&conn, &data->ioc_obdo1);
435 err = copy_to_user((int *)arg, data, sizeof(*data));
439 case OBD_IOC_BRW_WRITE:
441 case OBD_IOC_BRW_READ: {
442 /* FIXME: use a better ioctl data struct than obd_ioctl_data.
443 * We don't really support multiple-obdo I/Os here,
444 * for example offset and count are not per-obdo.
446 struct obd_conn conns[2];
447 struct obdo *obdos[2] = { NULL, NULL };
448 obd_count oa_bufs[2] = { 0, 0 };
449 struct page **bufs = NULL;
450 obd_size *counts = NULL;
451 obd_off *offsets = NULL;
452 obd_flag *flags = NULL;
457 pages = oa_bufs[0] = data->ioc_plen1 / PAGE_SIZE;
458 if (data->ioc_obdo2.o_id) {
460 oa_bufs[1] = data->ioc_plen2 / PAGE_SIZE;
464 CDEBUG(D_INODE, "BRW %s with %dx%d pages\n",
465 rw == OBD_BRW_READ ? "read" : "write",
467 bufs = kmalloc(pages * sizeof(*bufs), GFP_KERNEL);
468 counts = kmalloc(pages * sizeof(*counts), GFP_KERNEL);
469 offsets = kmalloc(pages * sizeof(*offsets), GFP_KERNEL);
470 flags = kmalloc(pages * sizeof(*flags), GFP_KERNEL);
471 if (!bufs || !counts || !offsets || !flags) {
472 CERROR("no memory for %d BRW per-page data\n", pages);
477 obdos[0] = &data->ioc_obdo1;
479 obdos[1] = &data->ioc_obdo2;
481 for (i = 0, pages = 0; i < num; i++) {
485 conns[i].oc_id = (&data->ioc_conn1)[i];
486 conns[i].oc_dev = obd;
488 from = (&data->ioc_pbuf1)[i];
489 off = data->ioc_offset;
491 for (j = 0; j < oa_bufs[i];
492 j++, pages++, off += PAGE_SIZE, from += PAGE_SIZE){
495 to = __get_free_pages(GFP_KERNEL, 0);
498 copy_from_user((void *)to,from,PAGE_SIZE))
501 CERROR("no memory for brw pages\n");
503 GOTO(brw_cleanup, err);
505 bufs[pages] = virt_to_page(to);
506 counts[pages] = PAGE_SIZE;
507 offsets[pages] = off;
512 err = obd_brw(rw, conns, num, obdos, oa_bufs, bufs,
513 counts, offsets, flags);
518 free_pages((unsigned long)page_address(bufs[pages]), 0);
527 conn.oc_id = data->ioc_conn1;
530 err = obd_iocontrol(cmd, &conn, sizeof(*data), data, NULL);
534 err = copy_to_user((int *)arg, data, sizeof(*data));
538 } /* obd_class_ioctl */
541 /* Driver interface done, utility functions follow */
542 int obd_register_type(struct obd_ops *ops, char *nm)
544 struct obd_type *type;
548 if (obd_init_magic != 0x11223344) {
549 CERROR("bad magic for type\n");
553 if (obd_nm_to_type(nm)) {
554 CDEBUG(D_IOCTL, "Type %s already registered\n", nm);
558 OBD_ALLOC(type, sizeof(*type));
561 INIT_LIST_HEAD(&type->typ_chain);
563 list_add(&type->typ_chain, obd_types.next);
569 int obd_unregister_type(char *nm)
571 struct obd_type *type = obd_nm_to_type(nm);
577 CERROR("unknown obd type\n");
581 if ( type->typ_refcnt ) {
583 CERROR("type %s has refcount (%d)\n", nm, type->typ_refcnt);
587 list_del(&type->typ_chain);
588 OBD_FREE(type, sizeof(*type));
591 } /* obd_unregister_type */
593 /* declare character device */
594 static struct file_operations obd_psdev_fops = {
595 ioctl: obd_class_ioctl, /* ioctl */
596 open: obd_class_open, /* open */
597 release: obd_class_release, /* release */
601 #define OBD_MINOR 241
602 static struct miscdevice obd_psdev = {
608 EXPORT_SYMBOL(obd_register_type);
609 EXPORT_SYMBOL(obd_unregister_type);
611 EXPORT_SYMBOL(obd_dev);
613 EXPORT_SYMBOL(gen_connect);
614 EXPORT_SYMBOL(gen_client);
615 EXPORT_SYMBOL(gen_cleanup);
616 EXPORT_SYMBOL(gen_disconnect);
617 EXPORT_SYMBOL(gen_copy_data);
618 EXPORT_SYMBOL(obdo_cachep);
620 /* EXPORT_SYMBOL(gen_multi_attach); */
621 EXPORT_SYMBOL(gen_multi_setup);
622 EXPORT_SYMBOL(gen_multi_cleanup);
623 EXPORT_SYMBOL(obd_memory);
624 EXPORT_SYMBOL(obd_fail_loc);
626 static int __init init_obdclass(void)
631 printk(KERN_INFO "OBD class driver v0.01, braam@stelias.com\n");
633 INIT_LIST_HEAD(&obd_types);
635 if ((err = misc_register(&obd_psdev))) {
636 CERROR("cannot register %d err %d\n", OBD_MINOR, err);
640 for (i = 0; i < MAX_OBD_DEVICES; i++) {
641 memset(&(obd_dev[i]), 0, sizeof(obd_dev[i]));
642 obd_dev[i].obd_minor = i;
643 INIT_LIST_HEAD(&obd_dev[i].obd_gen_clients);
644 INIT_LIST_HEAD(&obd_dev[i].obd_req_list);
645 init_waitqueue_head(&obd_dev[i].obd_req_waitq);
648 err = obd_init_obdo_cache();
652 obd_init_magic = 0x11223344;
656 static void __exit cleanup_obdclass(void)
661 misc_deregister(&obd_psdev);
662 for (i = 0; i < MAX_OBD_DEVICES; i++) {
663 struct obd_device *obd = &obd_dev[i];
664 if ( obd->obd_type &&
665 (obd->obd_flags & OBD_SET_UP) &&
666 OBT(obd) && OBP(obd, detach) ) {
667 /* XXX should this call generic detach otherwise? */
668 OBP(obd, detach)(obd);
672 obd_cleanup_obdo_cache();
674 CERROR("obd memory leaked: %ld bytes\n", obd_memory);
679 MODULE_AUTHOR("Cluster File Systems, Inc. <braam@clusterfs.com>");
680 MODULE_DESCRIPTION("Lustre Class Driver v1.0");
681 MODULE_LICENSE("GPL");
683 module_init(init_obdclass);
684 module_exit(cleanup_obdclass);