1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
6 * This code is issued under the GNU General Public License.
7 * See the file COPYING in this distribution
9 * These are the only exported functions, they provide some generic
10 * infrastructure for managing object devices
12 * Object Devices Class Driver
16 #include <linux/config.h> /* for CONFIG_PROC_FS */
17 #include <linux/module.h>
18 #include <linux/errno.h>
19 #include <linux/kernel.h>
20 #include <linux/major.h>
21 #include <linux/sched.h>
23 #include <linux/slab.h>
24 #include <linux/ioport.h>
25 #include <linux/fcntl.h>
26 #include <linux/delay.h>
27 #include <linux/skbuff.h>
28 #include <linux/proc_fs.h>
30 #include <linux/poll.h>
31 #include <linux/init.h>
32 #include <linux/list.h>
34 #include <asm/system.h>
36 #include <asm/uaccess.h>
37 #include <linux/miscdevice.h>
39 #define DEBUG_SUBSYSTEM S_CLASS
41 #include <linux/obd_support.h>
42 #include <linux/obd_class.h>
43 #include <linux/smp_lock.h>
45 struct semaphore obd_conf_sem; /* serialize configuration commands */
46 struct obd_device obd_dev[MAX_OBD_DEVICES];
47 struct list_head obd_types;
48 unsigned long obd_memory = 0;
49 unsigned long obd_fail_loc = 0;
51 extern struct obd_type *class_nm_to_type(char *nm);
53 /* opening /dev/obd */
54 static int obd_class_open(struct inode * inode, struct file * file)
58 file->private_data = NULL;
63 /* closing /dev/obd */
64 static int obd_class_release(struct inode * inode, struct file * file)
68 if (file->private_data)
69 file->private_data = NULL;
76 inline void obd_data2conn(struct lustre_handle *conn, struct obd_ioctl_data *data)
78 conn->addr = data->ioc_addr;
79 conn->cookie = data->ioc_cookie;
83 inline void obd_conn2data(struct obd_ioctl_data *data, struct lustre_handle *conn)
85 data->ioc_addr = conn->addr;
86 data->ioc_cookie = conn->cookie;
90 /* to control /dev/obd */
91 static int obd_class_ioctl (struct inode * inode, struct file * filp,
92 unsigned int cmd, unsigned long arg)
96 struct obd_ioctl_data *data;
97 struct obd_device *obd = filp->private_data;
98 struct lustre_handle conn;
99 int rw = OBD_BRW_READ;
105 if (!obd && cmd != OBD_IOC_DEVICE && cmd != TCGETS &&
106 cmd != OBD_IOC_LIST &&
107 cmd != OBD_IOC_NAME2DEV && cmd != OBD_IOC_NEWDEV) {
108 CERROR("OBD ioctl: No device\n");
109 GOTO(out, err=-EINVAL);
111 if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
112 CERROR("OBD ioctl: data error\n");
113 GOTO(out, err=-EINVAL);
115 data = (struct obd_ioctl_data *)buf;
119 GOTO(out, err=-EINVAL);
120 case OBD_IOC_DEVICE: {
121 CDEBUG(D_IOCTL, "\n");
122 if (data->ioc_dev >= MAX_OBD_DEVICES || data->ioc_dev < 0) {
123 CERROR("OBD ioctl: DEVICE insufficient devices\n");
124 GOTO(out, err=-EINVAL);
126 CDEBUG(D_IOCTL, "device %d\n", data->ioc_dev);
128 filp->private_data = &obd_dev[data->ioc_dev];
134 char *buf2 = data->ioc_bulk;
135 int remains = data->ioc_inllen1;
137 if (!data->ioc_inlbuf1) {
138 CERROR("No buffer passed!\n");
139 GOTO(out, err=-EINVAL);
143 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
146 struct obd_device *obd = &obd_dev[i];
149 if (obd->obd_flags & OBD_SET_UP)
153 l = snprintf(buf2, remains, "%2d %s %s %s %s\n",
154 i, status, obd->obd_type->typ_name,
155 obd->obd_name, obd->obd_uuid);
159 CERROR("not enough space for device listing\n");
164 err = copy_to_user((int *)arg, data, len);
169 case OBD_IOC_NAME2DEV: {
170 /* Resolve a device name. This does not change the
171 * currently selected device.
175 if (!data->ioc_inllen1 || !data->ioc_inlbuf1 ) {
176 CERROR("No name passed,!\n");
177 GOTO(out, err=-EINVAL);
179 if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
180 CERROR("Name not nul terminated!\n");
181 GOTO(out, err=-EINVAL);
184 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
185 dev = class_name2dev(data->ioc_inlbuf1);
188 CDEBUG(D_IOCTL, "No device for name %s!\n",
190 GOTO(out, err=-EINVAL);
193 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
195 err = copy_to_user((int *)arg, data, sizeof(*data));
199 case OBD_IOC_UUID2DEV: {
200 /* Resolve a device uuid. This does not change the
201 * currently selected device.
205 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
206 CERROR("No UUID passed!\n");
207 GOTO(out, err=-EINVAL);
209 if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
210 CERROR("Name not nul terminated!\n");
211 GOTO(out, err=-EINVAL);
214 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
215 dev = class_uuid2dev(data->ioc_inlbuf1);
218 CDEBUG(D_IOCTL, "No device for name %s!\n",
220 GOTO(out, err=-EINVAL);
223 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
225 err = copy_to_user((int *)arg, data, sizeof(*data));
229 case OBD_IOC_NEWDEV: {
233 filp->private_data = NULL;
234 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
235 struct obd_device *obd = &obd_dev[i];
236 if (!obd->obd_type) {
237 filp->private_data = obd;
246 GOTO(out, err=-EINVAL);
248 err = copy_to_user((int *)arg, data, sizeof(*data));
252 case OBD_IOC_ATTACH: {
253 struct obd_type *type;
255 /* have we attached a type to this device */
256 if (obd->obd_flags & OBD_ATTACHED) {
257 CERROR("OBD: Device %d already typed as %s.\n",
258 obd->obd_minor, MKSTR(obd->obd_type->typ_name));
259 GOTO(out, err=-EBUSY);
262 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
263 CERROR("No type passed!\n");
264 GOTO(out, err=-EINVAL);
266 if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
267 CERROR("Type not nul terminated!\n");
268 GOTO(out, err=-EINVAL);
271 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
272 MKSTR(data->ioc_inlbuf1),
273 MKSTR(data->ioc_inlbuf2), MKSTR(data->ioc_inlbuf3));
276 type = class_nm_to_type(data->ioc_inlbuf1);
278 CERROR("OBD: unknown type dev %d\n", obd->obd_minor);
279 GOTO(out, err=-EINVAL);
282 obd->obd_type = type;
283 INIT_LIST_HEAD(&obd->obd_exports);
286 if (OBP(obd, attach))
287 err = OBP(obd,attach)(obd, sizeof(*data), data);
289 obd->obd_type = NULL;
291 obd->obd_flags |= OBD_ATTACHED;
293 CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
294 obd->obd_minor, data->ioc_inlbuf1);
295 if (data->ioc_inlbuf2) {
296 int len = strlen(data->ioc_inlbuf2) + 1;
297 OBD_ALLOC(obd->obd_name, len);
298 if (!obd->obd_name) {
299 CERROR("no memory\n");
302 memcpy(obd->obd_name, data->ioc_inlbuf2, len);
303 obd->obd_proc_entry =
304 proc_lustre_register_obd_device(obd);
306 CERROR("WARNING: unnamed obd device\n");
307 obd->obd_proc_entry = NULL;
310 if (data->ioc_inlbuf3) {
311 int len = strlen(data->ioc_inlbuf3);
313 CERROR("uuid should be shorter than 37 bytes\n");
315 OBD_FREE(obd->obd_name,
316 strlen(obd->obd_name) + 1);
317 GOTO(out, err=-EINVAL);
319 memcpy(obd->obd_uuid, data->ioc_inlbuf3,
320 sizeof(obd->obd_uuid));
329 case OBD_IOC_DETACH: {
331 if (obd->obd_flags & OBD_SET_UP) {
332 CERROR("OBD device %d still set up\n", obd->obd_minor);
333 GOTO(out, err=-EBUSY);
335 if (! (obd->obd_flags & OBD_ATTACHED) ) {
336 CERROR("OBD device %d not attached\n", obd->obd_minor);
337 GOTO(out, err=-ENODEV);
339 if ( !list_empty(&obd->obd_exports) ) {
340 CERROR("OBD device %d has exports\n",
342 GOTO(out, err=-EBUSY);
346 OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
347 obd->obd_name = NULL;
350 if (obd->obd_proc_entry)
351 proc_lustre_release_obd_device(obd);
353 obd->obd_flags &= ~OBD_ATTACHED;
354 obd->obd_type->typ_refcnt--;
355 obd->obd_type = NULL;
360 case OBD_IOC_SETUP: {
361 /* have we attached a type to this device? */
362 if (!(obd->obd_flags & OBD_ATTACHED)) {
363 CERROR("Device %d not attached\n", obd->obd_minor);
364 GOTO(out, err=-ENODEV);
367 /* has this been done already? */
368 if ( obd->obd_flags & OBD_SET_UP ) {
369 CERROR("Device %d already setup (type %s)\n",
370 obd->obd_minor, obd->obd_type->typ_name);
371 GOTO(out, err=-EBUSY);
374 if ( OBT(obd) && OBP(obd, setup) )
375 err = obd_setup(obd, sizeof(*data), data);
378 obd->obd_type->typ_refcnt++;
379 obd->obd_flags |= OBD_SET_UP;
384 case OBD_IOC_CLEANUP: {
385 /* have we attached a type to this device? */
386 if (!(obd->obd_flags & OBD_ATTACHED)) {
387 CERROR("Device %d not attached\n", obd->obd_minor);
388 GOTO(out, err=-ENODEV);
391 if ( OBT(obd) && OBP(obd, cleanup) )
392 err = obd_cleanup(obd);
395 obd->obd_flags &= ~OBD_SET_UP;
396 obd->obd_type->typ_refcnt--;
401 case OBD_IOC_CONNECT: {
402 obd_data2conn(&conn, data);
404 err = obd_connect(&conn, obd, NULL);
406 CDEBUG(D_IOCTL, "assigned export %Lx\n", conn.addr);
407 obd_conn2data(data, &conn);
411 err = copy_to_user((int *)arg, data, sizeof(*data));
415 case OBD_IOC_DISCONNECT: {
416 obd_data2conn(&conn, data);
417 err = obd_disconnect(&conn);
421 case OBD_IOC_DEC_USE_COUNT: {
426 case OBD_IOC_CREATE: {
427 struct lov_stripe_md *ea;
428 obd_data2conn(&conn, data);
431 err = obd_create(&conn, &data->ioc_obdo1, &ea);
435 err = copy_to_user((int *)arg, data, sizeof(*data));
439 case OBD_IOC_GETATTR: {
441 obd_data2conn(&conn, data);
442 err = obd_getattr(&conn, &data->ioc_obdo1, NULL);
446 err = copy_to_user((int *)arg, data, sizeof(*data));
450 case OBD_IOC_SETATTR: {
451 obd_data2conn(&conn, data);
452 err = obd_setattr(&conn, &data->ioc_obdo1, NULL);
456 err = copy_to_user((int *)arg, data, sizeof(*data));
460 case OBD_IOC_DESTROY: {
462 obd_data2conn(&conn, data);
464 err = obd_destroy(&conn, &data->ioc_obdo1, NULL);
468 err = copy_to_user((int *)arg, data, sizeof(*data));
472 case OBD_IOC_BRW_WRITE:
474 case OBD_IOC_BRW_READ: {
475 struct lov_stripe_md smd;
477 struct page **bufs = NULL;
478 obd_size *counts = NULL;
479 obd_off *offsets = NULL;
480 obd_flag *flags = NULL;
485 obd_data2conn(&conn, data);
487 pages = data->ioc_plen1 / PAGE_SIZE;
489 CDEBUG(D_INODE, "BRW %s with %d pages\n",
490 rw == OBD_BRW_READ ? "read" : "write", pages);
491 OBD_ALLOC(bufs, pages * sizeof(*bufs));
492 OBD_ALLOC(counts, pages * sizeof(*counts));
493 OBD_ALLOC(offsets, pages * sizeof(*offsets));
494 OBD_ALLOC(flags, pages * sizeof(*flags));
495 if (!bufs || !counts || !offsets || !flags) {
496 CERROR("no memory for %d BRW per-page data\n", pages);
497 GOTO(brw_free, err = -ENOMEM);
500 memset(&smd, 0, sizeof(smd));
501 smd.lmd_object_id = data->ioc_obdo1.o_id;
503 from = (&data->ioc_pbuf1)[0];
504 off = data->ioc_offset;
506 for (j = 0; j < pages;
507 j++, off += PAGE_SIZE, from += PAGE_SIZE) {
510 to = __get_free_pages(GFP_KERNEL, 0);
514 *)to,from,PAGE_SIZE))
517 CERROR("no memory for brw pages\n");
518 GOTO(brw_cleanup, err = -ENOMEM);
520 bufs[j] = virt_to_page(to);
521 counts[j] = PAGE_SIZE;
526 err = obd_brw(rw, &conn, &smd, j, bufs, counts, offsets, flags,
531 for (j = 0; j < pages; j++)
533 __free_pages(bufs[j], 0);
535 OBD_FREE(bufs, pages * sizeof(*bufs));
536 OBD_FREE(counts, pages * sizeof(*counts));
537 OBD_FREE(offsets, pages * sizeof(*offsets));
538 OBD_FREE(flags, pages * sizeof(*flags));
542 obd_data2conn(&conn, data);
544 err = obd_iocontrol(cmd, &conn, len, data, NULL);
548 err = copy_to_user((int *)arg, data, len);
557 } /* obd_class_ioctl */
561 /* declare character device */
562 static struct file_operations obd_psdev_fops = {
563 ioctl: obd_class_ioctl, /* ioctl */
564 open: obd_class_open, /* open */
565 release: obd_class_release, /* release */
569 #define OBD_MINOR 241
570 static struct miscdevice obd_psdev = {
577 EXPORT_SYMBOL(obd_dev);
578 EXPORT_SYMBOL(obdo_cachep);
579 EXPORT_SYMBOL(obd_memory);
580 EXPORT_SYMBOL(obd_fail_loc);
582 EXPORT_SYMBOL(class_register_type);
583 EXPORT_SYMBOL(class_unregister_type);
584 EXPORT_SYMBOL(class_name2dev);
585 EXPORT_SYMBOL(class_uuid2dev);
586 EXPORT_SYMBOL(class_uuid2obd);
587 EXPORT_SYMBOL(class_new_export);
588 EXPORT_SYMBOL(class_connect);
589 EXPORT_SYMBOL(class_conn2export);
590 EXPORT_SYMBOL(class_rconn2export);
591 EXPORT_SYMBOL(class_conn2obd);
592 EXPORT_SYMBOL(class_disconnect);
593 EXPORT_SYMBOL(class_disconnect_all);
594 //EXPORT_SYMBOL(class_multi_setup);
595 //EXPORT_SYMBOL(class_multi_cleanup);
597 static int __init init_obdclass(void)
602 printk(KERN_INFO "OBD class driver v0.9, info@clusterfs.com\n");
604 sema_init(&obd_conf_sem, 1);
605 INIT_LIST_HEAD(&obd_types);
607 if ((err = misc_register(&obd_psdev))) {
608 CERROR("cannot register %d err %d\n", OBD_MINOR, err);
612 for (i = 0; i < MAX_OBD_DEVICES; i++) {
613 memset(&(obd_dev[i]), 0, sizeof(obd_dev[i]));
614 obd_dev[i].obd_minor = i;
615 INIT_LIST_HEAD(&obd_dev[i].obd_exports);
618 err = obd_init_caches();
625 static void __exit cleanup_obdclass(void)
630 misc_deregister(&obd_psdev);
631 for (i = 0; i < MAX_OBD_DEVICES; i++) {
632 struct obd_device *obd = &obd_dev[i];
633 if (obd->obd_type && (obd->obd_flags & OBD_SET_UP) &&
634 OBT(obd) && OBP(obd, detach)) {
635 /* XXX should this call generic detach otherwise? */
636 OBP(obd, detach)(obd);
640 obd_cleanup_caches();
642 CERROR("obd memory leaked: %ld bytes\n", obd_memory);
646 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
647 MODULE_DESCRIPTION("Lustre Class Driver v1.0");
648 MODULE_LICENSE("GPL");
650 module_init(init_obdclass);
651 module_exit(cleanup_obdclass);