Whamcloud - gitweb
1e180a86421e2c555b82733138ee967d3af73825
[fs/lustre-release.git] / lustre / obdclass / class_obd.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Object Devices Class Driver
5  *
6  *  Copyright (C) 2001-2003 Cluster File Systems, Inc.
7  *
8  *   This file is part of Lustre, http://www.lustre.org.
9  *
10  *   Lustre is free software; you can redistribute it and/or
11  *   modify it under the terms of version 2 of the GNU General Public
12  *   License as published by the Free Software Foundation.
13  *
14  *   Lustre is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *   GNU General Public License for more details.
18  *
19  *   You should have received a copy of the GNU General Public License
20  *   along with Lustre; if not, write to the Free Software
21  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  * These are the only exported functions, they provide some generic
24  * infrastructure for managing object devices
25  */
26
27 #define DEBUG_SUBSYSTEM S_CLASS
28 #define EXPORT_SYMTAB
29 #ifdef __KERNEL__
30 #include <linux/config.h> /* for CONFIG_PROC_FS */
31 #include <linux/module.h>
32 #include <linux/errno.h>
33 #include <linux/kernel.h>
34 #include <linux/major.h>
35 #include <linux/sched.h>
36 #include <linux/lp.h>
37 #include <linux/slab.h>
38 #include <linux/ioport.h>
39 #include <linux/fcntl.h>
40 #include <linux/delay.h>
41 #include <linux/skbuff.h>
42 #include <linux/proc_fs.h>
43 #include <linux/fs.h>
44 #include <linux/poll.h>
45 #include <linux/init.h>
46 #include <linux/list.h>
47 #include <linux/highmem.h>
48 #include <asm/io.h>
49 #include <asm/ioctls.h>
50 #include <asm/system.h>
51 #include <asm/poll.h>
52 #include <asm/uaccess.h>
53 #include <linux/miscdevice.h>
54 #include <linux/smp_lock.h>
55 #else
56
57 # include <liblustre.h>
58
59 #endif
60
61 #include <linux/obd_support.h>
62 #include <linux/obd_class.h>
63 #include <linux/lustre_debug.h>
64 #include <linux/lprocfs_status.h>
65 #include <portals/lib-types.h> /* for PTL_MD_MAX_IOV */
66 #include <linux/lustre_build_version.h>
67
68 struct semaphore obd_conf_sem;   /* serialize configuration commands */
69 struct obd_device obd_dev[MAX_OBD_DEVICES];
70 struct list_head obd_types;
71 atomic_t obd_memory;
72 int obd_memmax;
73
74 /* Root for /proc/lustre */
75 struct proc_dir_entry *proc_lustre_root = NULL;
76
77 /* The following are visible and mutable through /proc/sys/lustre/. */
78 unsigned long obd_fail_loc;
79 unsigned long obd_timeout = 100;
80 unsigned long obd_bulk_timeout = 1;
81 char obd_lustre_upcall[128] = "/usr/lib/lustre/lustre_upcall";
82 unsigned long obd_sync_filter; /* = 0, don't sync by default */
83
84 #ifdef __KERNEL__
85 /*  opening /dev/obd */
86 static int obd_class_open(struct inode * inode, struct file * file)
87 {
88         struct obd_class_user_state *ocus;
89         ENTRY;
90
91         OBD_ALLOC(ocus, sizeof(*ocus));
92         if (ocus == NULL)
93                 return (-ENOMEM);
94
95         INIT_LIST_HEAD(&ocus->ocus_conns);
96         file->private_data = ocus;
97
98         PORTAL_MODULE_USE;
99         RETURN(0);
100 }
101
102 /*  closing /dev/obd */
103 static int obd_class_release(struct inode * inode, struct file * file)
104 {
105         struct obd_class_user_state *ocus = file->private_data;
106         struct obd_class_user_conn  *c;
107         ENTRY;
108
109         while (!list_empty (&ocus->ocus_conns)) {
110                 c = list_entry (ocus->ocus_conns.next,
111                                 struct obd_class_user_conn, ocuc_chain);
112                 list_del (&c->ocuc_chain);
113
114                 CDEBUG (D_IOCTL, "Auto-disconnect %p\n", &c->ocuc_conn);
115
116                 down (&obd_conf_sem);
117                 obd_disconnect (&c->ocuc_conn, 0);
118                 up (&obd_conf_sem);
119
120                 OBD_FREE (c, sizeof (*c));
121         }
122
123         OBD_FREE (ocus, sizeof (*ocus));
124
125         PORTAL_MODULE_UNUSE;
126         RETURN(0);
127 }
128 #endif
129
130 static int
131 obd_class_add_user_conn (struct obd_class_user_state *ocus,
132                          struct lustre_handle *conn)
133 {
134         struct obd_class_user_conn *c;
135
136         /* NB holding obd_conf_sem */
137
138         OBD_ALLOC (c, sizeof (*c));
139         if (ocus == NULL)
140                 return (-ENOMEM);
141
142         c->ocuc_conn = *conn;
143         list_add (&c->ocuc_chain, &ocus->ocus_conns);
144         return (0);
145 }
146
147 static void
148 obd_class_remove_user_conn (struct obd_class_user_state *ocus,
149                             struct lustre_handle *conn)
150 {
151         struct list_head *e;
152         struct obd_class_user_conn *c;
153
154         /* NB holding obd_conf_sem or last reference */
155
156         list_for_each (e, &ocus->ocus_conns) {
157                 c = list_entry (e, struct obd_class_user_conn, ocuc_chain);
158                 if (conn->cookie == c->ocuc_conn.cookie) {
159                         list_del (&c->ocuc_chain);
160                         OBD_FREE (c, sizeof (*c));
161                         return;
162                 }
163         }
164 }
165
166 static inline void obd_data2conn(struct lustre_handle *conn,
167                                  struct obd_ioctl_data *data)
168 {
169         memset(conn, 0, sizeof *conn);
170         conn->cookie = data->ioc_cookie;
171 }
172
173 static inline void obd_conn2data(struct obd_ioctl_data *data,
174                                  struct lustre_handle *conn)
175 {
176         data->ioc_cookie = conn->cookie;
177 }
178
179 static void dump_exports(struct obd_device *obd)
180 {
181         struct list_head *tmp, *n;
182
183         list_for_each_safe(tmp, n, &obd->obd_exports) {
184                 struct obd_export *exp = list_entry(tmp, struct obd_export,
185                                                     exp_obd_chain);
186                 CDEBUG(D_ERROR, "%s: %p %s %d %d %p\n",
187                        obd->obd_name, exp, exp->exp_client_uuid.uuid,
188                        atomic_read(&exp->exp_refcount),
189                        exp->exp_failed, exp->exp_outstanding_reply );
190         }
191 }
192
193 int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd,
194                        unsigned long arg)
195 {
196         char *buf = NULL;
197         struct obd_ioctl_data *data;
198         struct portals_debug_ioctl_data *debug_data;
199         struct obd_device *obd = ocus->ocus_current_obd;
200         struct lustre_handle conn;
201         int err = 0, len = 0, serialised = 0;
202         ENTRY;
203
204         if ((cmd & 0xffffff00) == ((int)'T') << 8) /* ignore all tty ioctls */
205                 RETURN(err = -ENOTTY);
206
207         /* only for debugging */
208         if (cmd == PTL_IOC_DEBUG_MASK) {
209                 debug_data = (struct portals_debug_ioctl_data*)arg;
210                 portal_subsystem_debug = debug_data->subs;
211                 portal_debug = debug_data->debug;
212                 return 0;
213         }
214
215         switch (cmd) {
216         case OBD_IOC_BRW_WRITE:
217         case OBD_IOC_BRW_READ:
218         case OBD_IOC_GETATTR:
219         case ECHO_IOC_ENQUEUE:
220         case ECHO_IOC_CANCEL:
221                 break;
222         default:
223                 down(&obd_conf_sem);
224                 serialised = 1;
225                 break;
226         }
227
228         CDEBUG(D_IOCTL, "cmd = %x, obd = %p\n", cmd, obd);
229         if (!obd && cmd != OBD_IOC_DEVICE &&
230             cmd != OBD_IOC_LIST && cmd != OBD_GET_VERSION &&
231             cmd != OBD_IOC_NAME2DEV && cmd != OBD_IOC_UUID2DEV &&
232             cmd != OBD_IOC_NEWDEV && cmd != OBD_IOC_ADD_UUID &&
233             cmd != OBD_IOC_DEL_UUID && cmd != OBD_IOC_CLOSE_UUID) {
234                 CERROR("OBD ioctl: No device\n");
235                 GOTO(out, err = -EINVAL);
236         }
237         if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
238                 CERROR("OBD ioctl: data error\n");
239                 GOTO(out, err = -EINVAL);
240         }
241         data = (struct obd_ioctl_data *)buf;
242
243         switch (cmd) {
244         case OBD_IOC_DEVICE: {
245                 CDEBUG(D_IOCTL, "\n");
246                 if (data->ioc_dev >= MAX_OBD_DEVICES || data->ioc_dev < 0) {
247                         CERROR("OBD ioctl: DEVICE insufficient devices\n");
248                         GOTO(out, err = -EINVAL);
249                 }
250                 CDEBUG(D_IOCTL, "device %d\n", data->ioc_dev);
251
252                 ocus->ocus_current_obd = &obd_dev[data->ioc_dev];
253                 GOTO(out, err = 0);
254         }
255
256         case OBD_IOC_LIST: {
257                 int i;
258                 char *buf2 = data->ioc_bulk;
259                 int remains = data->ioc_inllen1;
260
261                 if (!data->ioc_inlbuf1) {
262                         CERROR("No buffer passed!\n");
263                         GOTO(out, err = -EINVAL);
264                 }
265
266
267                 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
268                         int l;
269                         char *status;
270                         struct obd_device *obd = &obd_dev[i];
271
272                         if (!obd->obd_type)
273                                 continue;
274                         if (obd->obd_stopping)
275                                 status = "ST";
276                         else if (obd->obd_set_up)
277                                 status = "UP";
278                         else if (obd->obd_attached)
279                                 status = "AT";
280                         else
281                                 status = "-";
282                         l = snprintf(buf2, remains, "%2d %s %s %s %s %d\n",
283                                      i, status, obd->obd_type->typ_name,
284                                      obd->obd_name, obd->obd_uuid.uuid,
285                                      obd->obd_type->typ_refcnt);
286                         buf2 +=l;
287                         remains -=l;
288                         if (remains <= 0) {
289                                 CERROR("not enough space for device listing\n");
290                                 break;
291                         }
292                 }
293
294                 err = copy_to_user((void *)arg, data, len);
295                 if (err)
296                         err = -EFAULT;
297                 GOTO(out, err);
298         }
299
300         case OBD_GET_VERSION:
301                 if (!data->ioc_inlbuf1) {
302                         CERROR("No buffer passed in ioctl\n");
303                         GOTO(out, err = -EINVAL);
304                 }
305
306                 if (strlen(BUILD_VERSION) + 1 > data->ioc_inllen1) {
307                         CERROR("ioctl buffer too small to hold version\n");
308                         GOTO(out, err = -EINVAL);
309                 }
310
311                 memcpy(data->ioc_bulk, BUILD_VERSION,
312                        strlen(BUILD_VERSION) + 1);
313
314                 err = copy_to_user((void *)arg, data, len);
315                 if (err)
316                         err = -EFAULT;
317                 GOTO(out, err);
318
319         case OBD_IOC_NAME2DEV: {
320                 /* Resolve a device name.  This does not change the
321                  * currently selected device.
322                  */
323                 int dev;
324
325                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1 ) {
326                         CERROR("No name passed,!\n");
327                         GOTO(out, err = -EINVAL);
328                 }
329                 if (data->ioc_inlbuf1[data->ioc_inllen1 - 1] != 0) {
330                         CERROR("Name not nul terminated!\n");
331                         GOTO(out, err = -EINVAL);
332                 }
333
334                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
335                 dev = class_name2dev(data->ioc_inlbuf1);
336                 data->ioc_dev = dev;
337                 if (dev == -1) {
338                         CDEBUG(D_IOCTL, "No device for name %s!\n",
339                                data->ioc_inlbuf1);
340                         GOTO(out, err = -EINVAL);
341                 }
342
343                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
344                        dev);
345                 err = copy_to_user((void *)arg, data, sizeof(*data));
346                 if (err)
347                         err = -EFAULT;
348                 GOTO(out, err);
349         }
350
351         case OBD_IOC_UUID2DEV: {
352                 /* Resolve a device uuid.  This does not change the
353                  * currently selected device.
354                  */
355                 int dev;
356                 struct obd_uuid uuid;
357
358                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
359                         CERROR("No UUID passed!\n");
360                         GOTO(out, err = -EINVAL);
361                 }
362                 if (data->ioc_inlbuf1[data->ioc_inllen1 - 1] != 0) {
363                         CERROR("UUID not NUL terminated!\n");
364                         GOTO(out, err = -EINVAL);
365                 }
366
367                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
368                 obd_str2uuid(&uuid, data->ioc_inlbuf1);
369                 dev = class_uuid2dev(&uuid);
370                 data->ioc_dev = dev;
371                 if (dev == -1) {
372                         CDEBUG(D_IOCTL, "No device for UUID %s!\n",
373                                data->ioc_inlbuf1);
374                         GOTO(out, err = -EINVAL);
375                 }
376
377                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
378                        dev);
379                 err = copy_to_user((void *)arg, data, sizeof(*data));
380                 if (err)
381                         err = -EFAULT;
382                 GOTO(out, err);
383         }
384
385
386
387         case OBD_IOC_NEWDEV: {
388                 int dev = -1;
389                 int i;
390
391                 ocus->ocus_current_obd = NULL;
392                 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
393                         struct obd_device *obd = &obd_dev[i];
394                         if (!obd->obd_type) {
395                                 ocus->ocus_current_obd = obd;
396                                 dev = i;
397                                 break;
398                         }
399                 }
400
401
402                 data->ioc_dev = dev;
403                 if (dev == -1)
404                         GOTO(out, err = -EINVAL);
405
406                 err = copy_to_user((void *)arg, data, sizeof(*data));
407                 if (err)
408                         err = -EFAULT;
409                 GOTO(out, err);
410         }
411
412         case OBD_IOC_ATTACH: {
413                 struct obd_type *type;
414                 int minor, len;
415
416                 /* have we attached a type to this device */
417                 if (obd->obd_attached|| obd->obd_type) {
418                         CERROR("OBD: Device %d already typed as %s.\n",
419                                obd->obd_minor, MKSTR(obd->obd_type->typ_name));
420                         GOTO(out, err = -EBUSY);
421                 }
422
423                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
424                         CERROR("No type passed!\n");
425                         GOTO(out, err = -EINVAL);
426                 }
427                 if (data->ioc_inlbuf1[data->ioc_inllen1 - 1] != 0) {
428                         CERROR("Type not nul terminated!\n");
429                         GOTO(out, err = -EINVAL);
430                 }
431                 if (!data->ioc_inllen2 || !data->ioc_inlbuf2) {
432                         CERROR("No name passed!\n");
433                         GOTO(out, err = -EINVAL);
434                 }
435                 if (data->ioc_inlbuf2[data->ioc_inllen2 - 1] != 0) {
436                         CERROR("Name not nul terminated!\n");
437                         GOTO(out, err = -EINVAL);
438                 }
439                 if (!data->ioc_inllen3 || !data->ioc_inlbuf3) {
440                         CERROR("No UUID passed!\n");
441                         GOTO(out, err = -EINVAL);
442                 }
443                 if (data->ioc_inlbuf3[data->ioc_inllen3 - 1] != 0) {
444                         CERROR("UUID not nul terminated!\n");
445                         GOTO(out, err = -EINVAL);
446                 }
447
448                 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
449                        MKSTR(data->ioc_inlbuf1),
450                        MKSTR(data->ioc_inlbuf2), MKSTR(data->ioc_inlbuf3));
451
452                 /* find the type */
453                 type = class_get_type(data->ioc_inlbuf1);
454                 if (!type) {
455                         CERROR("OBD: unknown type dev %d\n", obd->obd_minor);
456                         GOTO(out, err = -EINVAL);
457                 }
458
459                 minor = obd->obd_minor;
460                 memset(obd, 0, sizeof(*obd));
461                 obd->obd_minor = minor;
462                 obd->obd_type = type;
463                 INIT_LIST_HEAD(&obd->obd_exports);
464                 INIT_LIST_HEAD(&obd->obd_imports);
465                 spin_lock_init(&obd->obd_dev_lock);
466                 init_waitqueue_head(&obd->obd_refcount_waitq);
467
468                 /* XXX belong ins setup not attach  */
469                 /* recovery data */
470                 spin_lock_init(&obd->obd_processing_task_lock);
471                 init_waitqueue_head(&obd->obd_next_transno_waitq);
472                 INIT_LIST_HEAD(&obd->obd_recovery_queue);
473                 INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
474
475                 init_waitqueue_head(&obd->obd_commit_waitq);
476
477                 len = strlen(data->ioc_inlbuf2) + 1;
478                 OBD_ALLOC(obd->obd_name, len);
479                 if (!obd->obd_name) {
480                         class_put_type(obd->obd_type);
481                         obd->obd_type = NULL;
482                         GOTO(out, err = -ENOMEM);
483                 }
484                 memcpy(obd->obd_name, data->ioc_inlbuf2, len);
485
486                 len = strlen(data->ioc_inlbuf3);
487                 if (len >= sizeof(obd->obd_uuid)) {
488                         CERROR("uuid must be < "LPSZ" bytes long\n",
489                                sizeof(obd->obd_uuid));
490                         if (obd->obd_name)
491                                 OBD_FREE(obd->obd_name,
492                                          strlen(obd->obd_name) + 1);
493                         class_put_type(obd->obd_type);
494                         obd->obd_type = NULL;
495                         GOTO(out, err = -EINVAL);
496                 }
497                 memcpy(obd->obd_uuid.uuid, data->ioc_inlbuf3, len);
498
499                 /* do the attach */
500                 if (OBP(obd, attach))
501                         err = OBP(obd,attach)(obd, sizeof(*data), data);
502                 if (err) {
503                         if(data->ioc_inlbuf2)
504                                 OBD_FREE(obd->obd_name,
505                                          strlen(obd->obd_name) + 1);
506                         class_put_type(obd->obd_type);
507                         obd->obd_type = NULL;
508                 } else {
509                         obd->obd_attached = 1;
510
511                         type->typ_refcnt++;
512                         CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
513                                obd->obd_minor, data->ioc_inlbuf1);
514                 }
515
516                 GOTO(out, err);
517         }
518
519         case OBD_IOC_DETACH: {
520                 ENTRY;
521                 if (obd->obd_set_up) {
522                         CERROR("OBD device %d still set up\n", obd->obd_minor);
523                         GOTO(out, err = -EBUSY);
524                 }
525                 if (!obd->obd_attached) {
526                         CERROR("OBD device %d not attached\n", obd->obd_minor);
527                         GOTO(out, err = -ENODEV);
528                 }
529                 if (OBP(obd, detach))
530                         err = OBP(obd,detach)(obd);
531
532                 if (obd->obd_name) {
533                         OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
534                         obd->obd_name = NULL;
535                 }
536
537                 obd->obd_attached = 0;
538                 obd->obd_type->typ_refcnt--;
539                 class_put_type(obd->obd_type);
540                 obd->obd_type = NULL;
541                 GOTO(out, err = 0);
542         }
543
544         case OBD_IOC_SETUP: {
545                 /* have we attached a type to this device? */
546                 if (!obd->obd_attached) {
547                         CERROR("Device %d not attached\n", obd->obd_minor);
548                         GOTO(out, err = -ENODEV);
549                 }
550
551                 /* has this been done already? */
552                 if (obd->obd_set_up) {
553                         CERROR("Device %d already setup (type %s)\n",
554                                obd->obd_minor, obd->obd_type->typ_name);
555                         GOTO(out, err = -EBUSY);
556                 }
557
558                 atomic_set(&obd->obd_refcount, 0);
559
560                 if ( OBT(obd) && OBP(obd, setup) )
561                         err = obd_setup(obd, sizeof(*data), data);
562
563                 if (!err) {
564                         obd->obd_type->typ_refcnt++;
565                         obd->obd_set_up = 1;
566                         atomic_inc(&obd->obd_refcount);
567                 }
568
569                 GOTO(out, err);
570         }
571         case OBD_IOC_CLEANUP: {
572                 int force = 0, failover = 0;
573                 char * flag;
574
575                 if (!obd->obd_set_up) {
576                         CERROR("Device %d not setup\n", obd->obd_minor);
577                         GOTO(out, err = -ENODEV);
578                 }
579
580                 if (data->ioc_inlbuf1) {
581                         for (flag = data->ioc_inlbuf1; *flag != 0; flag++)
582                                 switch (*flag) {
583                                 case 'F':
584                                         force = 1;
585                                         break;
586                                 case 'A':
587                                         failover = 1;
588                                         break;
589                                 default:
590                                         CERROR("unrecognised flag '%c'\n", 
591                                                *flag);
592                                 }
593                 }
594                 
595                 if (atomic_read(&obd->obd_refcount) == 1 || force) {
596                         /* this will stop new connections, and need to
597                            do it before class_disconnect_exports() */
598                         obd->obd_stopping = 1;
599                 }
600
601                 if (atomic_read(&obd->obd_refcount) > 1) {
602                         struct l_wait_info lwi = LWI_TIMEOUT_INTR(60 * HZ, NULL,
603                                                                   NULL, NULL);
604                         int rc;
605                         
606                         if (!force) {
607                                 CERROR("OBD device %d (%p) has refcount %d\n",
608                                        obd->obd_minor, obd, 
609                                        atomic_read(&obd->obd_refcount));
610                                 dump_exports(obd);
611                                 GOTO(out, err = -EBUSY);
612                         }
613                         class_disconnect_exports(obd, failover);
614                         CDEBUG(D_IOCTL, 
615                                "%s: waiting for obd refs to go away: %d\n", 
616                                obd->obd_name, atomic_read(&obd->obd_refcount));
617                 
618                         rc = l_wait_event(obd->obd_refcount_waitq,
619                                      atomic_read(&obd->obd_refcount) < 2, &lwi);
620                         if (rc == 0) {
621                                 LASSERT(atomic_read(&obd->obd_refcount) == 1);
622                         } else {
623                                 CERROR("wait cancelled cleaning anyway. "
624                                        "refcount: %d\n",
625                                        atomic_read(&obd->obd_refcount));
626                                 dump_exports(obd);
627                         }
628                         CDEBUG(D_IOCTL, "%s: awake, now finishing cleanup\n", 
629                                obd->obd_name);
630                 }
631
632                 if (OBT(obd) && OBP(obd, cleanup))
633                         err = obd_cleanup(obd, force, failover);
634
635                 if (!err) {
636                         obd->obd_set_up = obd->obd_stopping = 0;
637                         obd->obd_type->typ_refcnt--;
638                         atomic_dec(&obd->obd_refcount);
639                         /* XXX this should be an LASSERT */
640                         if (atomic_read(&obd->obd_refcount) > 0) 
641                                 CERROR("%s still has refcount %d after "
642                                        "cleanup.\n", obd->obd_name,
643                                        atomic_read(&obd->obd_refcount));
644                 }
645
646                 GOTO(out, err);
647         }
648
649         case OBD_IOC_CONNECT: {
650                 struct obd_uuid cluuid = { "OBD_CLASS_UUID" };
651                 obd_data2conn(&conn, data);
652
653                 err = obd_connect(&conn, obd, &cluuid);
654
655                 CDEBUG(D_IOCTL, "assigned export "LPX64"\n", conn.cookie);
656                 obd_conn2data(data, &conn);
657                 if (err)
658                         GOTO(out, err);
659
660                 err = obd_class_add_user_conn (ocus, &conn);
661                 if (err != 0) {
662                         obd_disconnect (&conn, 0);
663                         GOTO (out, err);
664                 }
665
666                 err = copy_to_user((void *)arg, data, sizeof(*data));
667                 if (err != 0) {
668                         obd_class_remove_user_conn (ocus, &conn);
669                         obd_disconnect (&conn, 0);
670                         GOTO (out, err = -EFAULT);
671                 }
672                 GOTO(out, err);
673         }
674
675         case OBD_IOC_DISCONNECT: {
676                 obd_data2conn(&conn, data);
677                 obd_class_remove_user_conn (ocus, &conn);
678                 err = obd_disconnect(&conn, 0);
679                 GOTO(out, err);
680         }
681
682         case OBD_IOC_NO_TRANSNO: {
683                 if (!obd->obd_attached) {
684                         CERROR("Device %d not attached\n", obd->obd_minor);
685                         GOTO(out, err = -ENODEV);
686                 }
687                 CDEBUG(D_IOCTL,
688                        "disabling committed-transno notifications on %d\n",
689                        obd->obd_minor);
690                 obd->obd_no_transno = 1;
691                 GOTO(out, err = 0);
692         }
693
694         case OBD_IOC_CLOSE_UUID: {
695                 struct lustre_peer peer;
696                 CDEBUG(D_IOCTL, "closing all connections to uuid %s\n",
697                        data->ioc_inlbuf1);
698                 lustre_uuid_to_peer(data->ioc_inlbuf1, &peer);
699                 GOTO(out, err = 0);
700         }
701         case OBD_IOC_ADD_UUID: {
702                 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
703                        ", nal %d\n", data->ioc_inlbuf1, data->ioc_nid,
704                        data->ioc_nal);
705
706                 err = class_add_uuid(data->ioc_inlbuf1, data->ioc_nid,
707                                      data->ioc_nal);
708                 GOTO(out, err);
709         }
710         case OBD_IOC_DEL_UUID: {
711                 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
712                        data->ioc_inlbuf1 == NULL ? "<all uuids>" :
713                        data->ioc_inlbuf1);
714
715                 err = class_del_uuid(data->ioc_inlbuf1);
716                 GOTO(out, err);
717         }
718         default: { 
719                 // obd_data2conn(&conn, data);
720                 struct obd_class_user_conn *oconn = list_entry(ocus->ocus_conns.next, struct obd_class_user_conn, ocuc_chain);
721                 err = obd_iocontrol(cmd, &oconn->ocuc_conn, len, data, NULL);
722                 if (err)
723                         GOTO(out, err);
724
725                 err = copy_to_user((void *)arg, data, len);
726                 if (err)
727                         err = -EFAULT;
728                 GOTO(out, err);
729         }
730         }
731
732  out:
733         if (buf)
734                 obd_ioctl_freedata(buf, len);
735         if (serialised)
736                 up(&obd_conf_sem);
737         RETURN(err);
738 } /* class_handle_ioctl */
739
740
741
742 #define OBD_MINOR 241
743 #ifdef __KERNEL__
744 /* to control /dev/obd */
745 static int obd_class_ioctl(struct inode *inode, struct file *filp,
746                            unsigned int cmd, unsigned long arg)
747 {
748         return class_handle_ioctl(filp->private_data, cmd, arg);
749 }
750
751 /* declare character device */
752 static struct file_operations obd_psdev_fops = {
753         ioctl:   obd_class_ioctl,       /* ioctl */
754         open:    obd_class_open,        /* open */
755         release: obd_class_release,     /* release */
756 };
757
758 /* modules setup */
759 static struct miscdevice obd_psdev = {
760         OBD_MINOR,
761         "obd_psdev",
762         &obd_psdev_fops
763 };
764 #else
765 void *obd_psdev = NULL;
766 #endif
767
768 EXPORT_SYMBOL(obd_dev);
769 EXPORT_SYMBOL(obdo_cachep);
770 EXPORT_SYMBOL(obd_memory);
771 EXPORT_SYMBOL(obd_memmax);
772 EXPORT_SYMBOL(obd_fail_loc);
773 EXPORT_SYMBOL(obd_timeout);
774 EXPORT_SYMBOL(obd_lustre_upcall);
775 EXPORT_SYMBOL(obd_sync_filter);
776 EXPORT_SYMBOL(ptlrpc_put_connection_superhack);
777 EXPORT_SYMBOL(ptlrpc_abort_inflight_superhack);
778 EXPORT_SYMBOL(proc_lustre_root);
779
780 EXPORT_SYMBOL(lctl_fake_uuid);
781
782 EXPORT_SYMBOL(class_register_type);
783 EXPORT_SYMBOL(class_unregister_type);
784 EXPORT_SYMBOL(class_get_type);
785 EXPORT_SYMBOL(class_put_type);
786 EXPORT_SYMBOL(class_name2dev);
787 EXPORT_SYMBOL(class_uuid2dev);
788 EXPORT_SYMBOL(class_uuid2obd);
789 EXPORT_SYMBOL(class_export_get);
790 EXPORT_SYMBOL(class_export_put);
791 EXPORT_SYMBOL(class_new_export);
792 EXPORT_SYMBOL(class_unlink_export);
793 EXPORT_SYMBOL(class_import_get);
794 EXPORT_SYMBOL(class_import_put);
795 EXPORT_SYMBOL(class_new_import);
796 EXPORT_SYMBOL(class_destroy_import);
797 EXPORT_SYMBOL(class_connect);
798 EXPORT_SYMBOL(class_conn2export);
799 EXPORT_SYMBOL(class_conn2obd);
800 EXPORT_SYMBOL(class_conn2cliimp);
801 EXPORT_SYMBOL(class_conn2ldlmimp);
802 EXPORT_SYMBOL(class_disconnect);
803 EXPORT_SYMBOL(class_disconnect_exports);
804 EXPORT_SYMBOL(lustre_uuid_to_peer);
805
806 /* uuid.c */
807 EXPORT_SYMBOL(class_uuid_unparse);
808 EXPORT_SYMBOL(client_tgtuuid2obd);
809
810 EXPORT_SYMBOL(class_handle_hash);
811 EXPORT_SYMBOL(class_handle_unhash);
812 EXPORT_SYMBOL(class_handle2object);
813
814 #ifdef __KERNEL__
815 static int __init init_obdclass(void)
816 #else
817 int init_obdclass(void)
818 #endif
819 {
820         struct obd_device *obd;
821         int err;
822         int i;
823
824         printk(KERN_INFO "OBD class driver Build Version: " BUILD_VERSION
825                       ", info@clusterfs.com\n");
826
827         class_init_uuidlist();
828         class_handle_init();
829
830         sema_init(&obd_conf_sem, 1);
831         INIT_LIST_HEAD(&obd_types);
832
833         if ((err = misc_register(&obd_psdev))) {
834                 CERROR("cannot register %d err %d\n", OBD_MINOR, err);
835                 return err;
836         }
837
838         /* This struct is already zerod for us (static global) */
839         for (i = 0, obd = obd_dev; i < MAX_OBD_DEVICES; i++, obd++)
840                 obd->obd_minor = i;
841
842         err = obd_init_caches();
843         if (err)
844                 return err;
845
846 #ifdef __KERNEL__
847         obd_sysctl_init();
848 #endif
849
850 #ifdef LPROCFS
851         proc_lustre_root = proc_mkdir("lustre", proc_root_fs);
852         if (!proc_lustre_root)
853                 printk(KERN_ERR "error registering /proc/fs/lustre\n");
854 #else
855         proc_lustre_root = NULL;
856 #endif
857         return 0;
858 }
859
860 #ifdef __KERNEL__
861 static void __exit cleanup_obdclass(void)
862 #else
863 static void cleanup_obdclass(void)
864 #endif
865 {
866         int i;
867         ENTRY;
868
869         misc_deregister(&obd_psdev);
870         for (i = 0; i < MAX_OBD_DEVICES; i++) {
871                 struct obd_device *obd = &obd_dev[i];
872                 if (obd->obd_type && obd->obd_set_up &&
873                     OBT(obd) && OBP(obd, detach)) {
874                         /* XXX should this call generic detach otherwise? */
875                         OBP(obd, detach)(obd);
876                 }
877         }
878
879         obd_cleanup_caches();
880 #ifdef __KERNEL__
881         obd_sysctl_clean();
882 #endif
883         if (proc_lustre_root) {
884                 lprocfs_remove(proc_lustre_root);
885                 proc_lustre_root = NULL;
886         }
887
888         class_handle_cleanup();
889         class_exit_uuidlist();
890
891         CERROR("obd mem max: %d leaked: %d\n", obd_memmax,
892                atomic_read(&obd_memory));
893         EXIT;
894 }
895
896 /* Check that we're building against the appropriate version of the Lustre
897  * kernel patch */
898 #ifdef __KERNEL__
899 #include <linux/lustre_version.h>
900 #define LUSTRE_MIN_VERSION 18
901 #define LUSTRE_MAX_VERSION 19
902 #if (LUSTRE_KERNEL_VERSION < LUSTRE_MIN_VERSION)
903 # error Cannot continue: Your Lustre kernel patch is older than the sources
904 #elif (LUSTRE_KERNEL_VERSION > LUSTRE_MAX_VERSION)
905 # error Cannot continue: Your Lustre sources are older than the kernel patch
906 #endif
907  #else
908 # warning "Lib Lustre - no versioning information"
909 #endif
910
911 #ifdef __KERNEL__
912 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
913 MODULE_DESCRIPTION("Lustre Class Driver Build Version: " BUILD_VERSION);
914 MODULE_LICENSE("GPL");
915
916 module_init(init_obdclass);
917 module_exit(cleanup_obdclass);
918 #endif