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;
69 /* opening /dev/obd */
70 static int obd_class_open(struct inode * inode, struct file * file)
74 file->private_data = NULL;
79 /* closing /dev/obd */
80 static int obd_class_release(struct inode * inode, struct file * file)
84 if (file->private_data)
85 file->private_data = NULL;
91 int obd_class_name2dev(char *name)
96 for (i=0; i < MAX_OBD_DEVICES; i++) {
97 struct obd_device *obd = &obd_dev[i];
98 if (obd->obd_name && strcmp(name, obd->obd_name) == 0) {
107 int obd_class_uuid2dev(char *name)
112 for (i=0; i < MAX_OBD_DEVICES; i++) {
113 struct obd_device *obd = &obd_dev[i];
114 if (obd->obd_name && strncmp(name, obd->obd_uuid, 37) == 0) {
124 * support functions: we could use inter-module communication, but this
125 * is more portable to other OS's
127 static struct obd_type *obd_search_type(char *nm)
129 struct list_head *tmp;
130 struct obd_type *type;
131 CDEBUG(D_INFO, "SEARCH %s\n", nm);
134 while ( (tmp = tmp->next) != &obd_types ) {
135 type = list_entry(tmp, struct obd_type, typ_chain);
136 CDEBUG(D_INFO, "TYP %s\n", type->typ_name);
137 if (strlen(type->typ_name) == strlen(nm) &&
138 strcmp(type->typ_name, nm) == 0 ) {
145 static struct obd_type *obd_nm_to_type(char *nm)
147 struct obd_type *type = obd_search_type(nm);
151 if ( !request_module(nm) ) {
152 CDEBUG(D_INFO, "Loaded module '%s'\n", nm);
153 type = obd_search_type(nm);
155 CDEBUG(D_INFO, "Can't load module '%s'\n", nm);
162 inline void obd_data2conn(struct obd_conn *conn, struct obd_ioctl_data *data)
164 conn->addr = data->ioc_addr;
165 conn->cookie = data->ioc_cookie;
169 inline void obd_conn2data(struct obd_ioctl_data *data, struct obd_conn *conn)
171 data->ioc_addr = conn->addr;
172 data->ioc_cookie = conn->cookie;
176 /* to control /dev/obd */
177 static int obd_class_ioctl (struct inode * inode, struct file * filp,
178 unsigned int cmd, unsigned long arg)
180 /* NOTE this must be larger than any of the ioctl data structs */
183 struct obd_ioctl_data *data;
184 struct obd_device *obd = filp->private_data;
185 struct obd_conn conn;
186 int rw = OBD_BRW_READ;
190 memset(buf, 0, sizeof(buf));
192 if (!obd && cmd != OBD_IOC_DEVICE && cmd != TCGETS &&
193 cmd != OBD_IOC_LIST &&
194 cmd != OBD_IOC_NAME2DEV && cmd != OBD_IOC_NEWDEV) {
195 CERROR("OBD ioctl: No device\n");
198 if (obd_ioctl_getdata(buf, &len, (void *)arg)) {
199 CERROR("OBD ioctl: data error\n");
202 data = (struct obd_ioctl_data *)buf;
207 case OBD_IOC_DEVICE: {
208 CDEBUG(D_IOCTL, "\n");
209 if (data->ioc_dev >= MAX_OBD_DEVICES || data->ioc_dev < 0) {
210 CERROR("OBD ioctl: DEVICE insufficient devices\n");
213 CDEBUG(D_IOCTL, "device %d\n", data->ioc_dev);
215 filp->private_data = &obd_dev[data->ioc_dev];
221 char *buf = data->ioc_bulk;
222 int remains = data->ioc_inllen1;
224 if (!data->ioc_inlbuf1) {
225 CERROR("No buffer passed!\n");
230 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
232 struct obd_device *obd = &obd_dev[i];
235 l = snprintf(buf, remains, "%2d %s %s %s\n",
236 i, obd->obd_type->typ_name,
237 obd->obd_name, obd->obd_uuid);
241 CERROR("not enough space for device listing\n");
246 err = copy_to_user((int *)arg, data, len);
251 case OBD_IOC_NAME2DEV: {
252 /* Resolve a device name. This does not change the
253 * currently selected device.
257 if (!data->ioc_inlbuf1) {
258 CERROR("No name passed!\n");
261 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
262 dev = obd_class_name2dev(data->ioc_inlbuf1);
265 CDEBUG(D_IOCTL, "No device for name %s!\n",
270 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
272 err = copy_to_user((int *)arg, data, sizeof(*data));
276 case OBD_IOC_UUID2DEV: {
277 /* Resolve a device uuid. This does not change the
278 * currently selected device.
282 if (!data->ioc_inlbuf1) {
283 CERROR("No UUID passed!\n");
286 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
287 dev = obd_class_uuid2dev(data->ioc_inlbuf1);
290 CDEBUG(D_IOCTL, "No device for name %s!\n",
295 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
297 err = copy_to_user((int *)arg, data, sizeof(*data));
301 case OBD_IOC_NEWDEV: {
305 filp->private_data = NULL;
306 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
307 struct obd_device *obd = &obd_dev[i];
308 if (!obd->obd_type) {
309 filp->private_data = obd;
320 err = copy_to_user((int *)arg, data, sizeof(*data));
324 case OBD_IOC_ATTACH: {
325 struct obd_type *type;
327 /* have we attached a type to this device */
328 if (obd->obd_flags & OBD_ATTACHED) {
329 CERROR("OBD: Device %d already typed as %s.\n",
330 obd->obd_minor, MKSTR(obd->obd_type->typ_name));
334 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
335 MKSTR(data->ioc_inlbuf1),
336 MKSTR(data->ioc_inlbuf2), MKSTR(data->ioc_inlbuf3));
339 type = obd_nm_to_type(data->ioc_inlbuf1);
341 CERROR("OBD: unknown type dev %d\n", obd->obd_minor);
345 obd->obd_type = type;
346 obd->obd_multi_count = 0;
347 INIT_LIST_HEAD(&obd->obd_exports);
350 if (OBT(obd) && OBP(obd, attach))
351 err = OBP(obd,attach)(obd, sizeof(*data), data);
353 obd->obd_type = NULL;
355 obd->obd_flags |= OBD_ATTACHED;
357 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
358 obd->obd_minor, data->ioc_inlbuf1);
359 obd->obd_proc_entry =
360 proc_lustre_register_obd_device(obd);
361 if (data->ioc_inlbuf2) {
362 int len = strlen(data->ioc_inlbuf2) + 1;
363 OBD_ALLOC(obd->obd_name, len + 1);
364 if (!obd->obd_name) {
365 CERROR("no memory\n");
368 memcpy(obd->obd_name, data->ioc_inlbuf2, len + 1);
370 if (data->ioc_inlbuf3) {
371 int len = strlen(data->ioc_inlbuf3);
373 CERROR("uuid should be shorter than 37 bytes\n");
375 OBD_FREE(obd->obd_name,
376 strlen(obd->obd_name) + 1);
379 memcpy(obd->obd_uuid, data->ioc_inlbuf3,
380 sizeof(obd->obd_uuid));
389 case OBD_IOC_DETACH: {
391 if (obd->obd_flags & OBD_SET_UP) {
392 CERROR("OBD device %d still set up\n", obd->obd_minor);
395 if (! (obd->obd_flags & OBD_ATTACHED) ) {
396 CERROR("OBD device %d not attached\n", obd->obd_minor);
399 if ( !list_empty(&obd->obd_exports) ) {
400 CERROR("OBD device %d has exports\n",
406 OBD_FREE(obd->obd_name, strlen(obd->obd_name)+ 1);
407 obd->obd_name = NULL;
410 if (obd->obd_proc_entry)
411 proc_lustre_release_obd_device(obd);
413 obd->obd_flags &= ~OBD_ATTACHED;
414 obd->obd_type->typ_refcnt--;
415 obd->obd_type = NULL;
420 case OBD_IOC_SETUP: {
421 /* have we attached a type to this device? */
422 if (!(obd->obd_flags & OBD_ATTACHED)) {
423 CERROR("Device %d not attached\n", obd->obd_minor);
427 /* has this been done already? */
428 if ( obd->obd_flags & OBD_SET_UP ) {
429 CERROR("Device %d already setup (type %s)\n",
430 obd->obd_minor, obd->obd_type->typ_name);
434 if ( OBT(obd) && OBP(obd, setup) )
435 err = obd_setup(obd, sizeof(*data), data);
438 obd->obd_type->typ_refcnt++;
439 obd->obd_flags |= OBD_SET_UP;
444 case OBD_IOC_CLEANUP: {
445 /* have we attached a type to this device? */
446 if (!(obd->obd_flags & OBD_ATTACHED)) {
447 CERROR("Device %d not attached\n", obd->obd_minor);
451 if ( OBT(obd) && OBP(obd, cleanup) )
452 err = obd_cleanup(obd);
455 obd->obd_flags &= ~OBD_SET_UP;
456 obd->obd_type->typ_refcnt--;
461 case OBD_IOC_CONNECT: {
462 obd_data2conn(&conn, data);
464 err = obd_connect(&conn, obd);
466 CDEBUG(D_IOCTL, "assigned connection %d\n", conn.oc_id);
467 obd_conn2data(data, &conn);
471 err = copy_to_user((int *)arg, data, sizeof(*data));
475 case OBD_IOC_DISCONNECT: {
476 obd_data2conn(&conn, data);
477 err = obd_disconnect(&conn);
481 case OBD_IOC_DEC_USE_COUNT: {
486 case OBD_IOC_CREATE: {
487 obd_data2conn(&conn, data);
489 err = obd_create(&conn, &data->ioc_obdo1);
493 err = copy_to_user((int *)arg, data, sizeof(*data));
497 case OBD_IOC_GETATTR: {
499 obd_data2conn(&conn, data);
500 err = obd_getattr(&conn, &data->ioc_obdo1);
504 err = copy_to_user((int *)arg, data, sizeof(*data));
508 case OBD_IOC_SETATTR: {
509 obd_data2conn(&conn, data);
510 err = obd_setattr(&conn, &data->ioc_obdo1);
514 err = copy_to_user((int *)arg, data, sizeof(*data));
518 case OBD_IOC_DESTROY: {
519 obd_data2conn(&conn, data);
521 err = obd_destroy(&conn, &data->ioc_obdo1);
525 err = copy_to_user((int *)arg, data, sizeof(*data));
529 case OBD_IOC_BRW_WRITE:
531 case OBD_IOC_BRW_READ: {
532 /* FIXME: use a better ioctl data struct than obd_ioctl_data.
533 * We don't really support multiple-obdo I/Os here,
534 * for example offset and count are not per-obdo.
536 struct obdo *obdos[2] = { NULL, NULL };
537 obd_count oa_bufs[2] = { 0, 0 };
538 struct page **bufs = NULL;
539 obd_size *counts = NULL;
540 obd_off *offsets = NULL;
541 obd_flag *flags = NULL;
546 obd_data2conn(&conn, data);
548 pages = oa_bufs[0] = data->ioc_plen1 / PAGE_SIZE;
549 if (data->ioc_obdo2.o_id) {
551 oa_bufs[1] = data->ioc_plen2 / PAGE_SIZE;
555 CDEBUG(D_INODE, "BRW %s with %dx%d pages\n",
556 rw == OBD_BRW_READ ? "read" : "write",
558 OBD_ALLOC(bufs, pages * sizeof(*bufs));
559 OBD_ALLOC(counts, pages * sizeof(*counts));
560 OBD_ALLOC(offsets, pages * sizeof(*offsets));
561 OBD_ALLOC(flags, pages * sizeof(*flags));
562 if (!bufs || !counts || !offsets || !flags) {
563 CERROR("no memory for %d BRW per-page data\n", pages);
568 obdos[0] = &data->ioc_obdo1;
570 obdos[1] = &data->ioc_obdo2;
572 for (i = 0, pages = 0; i < num; i++) {
576 from = (&data->ioc_pbuf1)[i];
577 off = data->ioc_offset;
579 for (j = 0; j < oa_bufs[i];
580 j++, pages++, off += PAGE_SIZE, from += PAGE_SIZE){
583 to = __get_free_pages(GFP_KERNEL, 0);
586 copy_from_user((void *)to,from,PAGE_SIZE))
589 CERROR("no memory for brw pages\n");
591 GOTO(brw_cleanup, err);
593 bufs[pages] = virt_to_page(to);
594 counts[pages] = PAGE_SIZE;
595 offsets[pages] = off;
600 err = obd_brw(rw, &conn, num, obdos, oa_bufs, bufs,
601 counts, offsets, flags, NULL);
607 __free_pages(bufs[i], 0);
609 OBD_FREE(bufs, pages * sizeof(*bufs));
610 OBD_FREE(counts, pages * sizeof(*counts));
611 OBD_FREE(offsets, pages * sizeof(*offsets));
612 OBD_FREE(flags, pages * sizeof(*flags));
616 obd_data2conn(&conn, data);
618 err = obd_iocontrol(cmd, &conn, sizeof(*data), data, NULL);
622 err = copy_to_user((int *)arg, data, sizeof(*data));
626 } /* obd_class_ioctl */
629 /* Driver interface done, utility functions follow */
630 int obd_register_type(struct obd_ops *ops, char *nm)
632 struct obd_type *type;
636 if (obd_init_magic != 0x11223344) {
637 CERROR("bad magic for type\n");
641 if (obd_nm_to_type(nm)) {
642 CDEBUG(D_IOCTL, "Type %s already registered\n", nm);
646 OBD_ALLOC(type, sizeof(*type));
649 INIT_LIST_HEAD(&type->typ_chain);
651 list_add(&type->typ_chain, obd_types.next);
657 int obd_unregister_type(char *nm)
659 struct obd_type *type = obd_nm_to_type(nm);
665 CERROR("unknown obd type\n");
669 if ( type->typ_refcnt ) {
671 CERROR("type %s has refcount (%d)\n", nm, type->typ_refcnt);
675 list_del(&type->typ_chain);
676 OBD_FREE(type, sizeof(*type));
679 } /* obd_unregister_type */
681 /* declare character device */
682 static struct file_operations obd_psdev_fops = {
683 ioctl: obd_class_ioctl, /* ioctl */
684 open: obd_class_open, /* open */
685 release: obd_class_release, /* release */
689 #define OBD_MINOR 241
690 static struct miscdevice obd_psdev = {
696 EXPORT_SYMBOL(obd_register_type);
697 EXPORT_SYMBOL(obd_unregister_type);
699 EXPORT_SYMBOL(obd_dev);
700 EXPORT_SYMBOL(obd_class_name2dev);
701 EXPORT_SYMBOL(obd_class_uuid2dev);
702 EXPORT_SYMBOL(gen_connect);
703 EXPORT_SYMBOL(gen_client);
704 EXPORT_SYMBOL(gen_conn2obd);
705 EXPORT_SYMBOL(gen_cleanup);
706 EXPORT_SYMBOL(gen_disconnect);
707 EXPORT_SYMBOL(gen_copy_data);
708 EXPORT_SYMBOL(obdo_cachep);
710 /* EXPORT_SYMBOL(gen_multi_attach); */
711 EXPORT_SYMBOL(gen_multi_setup);
712 EXPORT_SYMBOL(gen_multi_cleanup);
713 EXPORT_SYMBOL(obd_memory);
714 EXPORT_SYMBOL(obd_fail_loc);
716 static int __init init_obdclass(void)
721 printk(KERN_INFO "OBD class driver v0.9, info@clusterfs.com\n");
723 INIT_LIST_HEAD(&obd_types);
725 if ((err = misc_register(&obd_psdev))) {
726 CERROR("cannot register %d err %d\n", OBD_MINOR, err);
730 for (i = 0; i < MAX_OBD_DEVICES; i++) {
731 memset(&(obd_dev[i]), 0, sizeof(obd_dev[i]));
732 obd_dev[i].obd_minor = i;
733 INIT_LIST_HEAD(&obd_dev[i].obd_exports);
736 err = obd_init_caches();
740 obd_init_magic = 0x11223344;
744 static void __exit cleanup_obdclass(void)
749 misc_deregister(&obd_psdev);
750 for (i = 0; i < MAX_OBD_DEVICES; i++) {
751 struct obd_device *obd = &obd_dev[i];
752 if (obd->obd_type && (obd->obd_flags & OBD_SET_UP) &&
753 OBT(obd) && OBP(obd, detach)) {
754 /* XXX should this call generic detach otherwise? */
755 OBP(obd, detach)(obd);
759 obd_cleanup_caches();
761 CERROR("obd memory leaked: %ld bytes\n", obd_memory);
766 MODULE_AUTHOR("Cluster File Systems, Inc. <braam@clusterfs.com>");
767 MODULE_DESCRIPTION("Lustre Class Driver v1.0");
768 MODULE_LICENSE("GPL");
770 module_init(init_obdclass);
771 module_exit(cleanup_obdclass);