Whamcloud - gitweb
merge b_devel into HEAD. Includes:
[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 #else
55
56 # include <liblustre.h>
57
58 #endif
59
60 #include <linux/obd_support.h>
61 #include <linux/obd_class.h>
62 #include <linux/lustre_debug.h>
63 #include <linux/smp_lock.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 char obd_recovery_upcall[128] = "/usr/lib/lustre/ha_assist";
81 unsigned long obd_sync_filter; /* = 0, don't sync by default */
82
83 /*  opening /dev/obd */
84 static int obd_class_open(struct inode * inode, struct file * file)
85 {
86         struct obd_class_user_state *ocus;
87         ENTRY;
88
89         OBD_ALLOC(ocus, sizeof(*ocus));
90         if (ocus == NULL)
91                 return (-ENOMEM);
92
93         INIT_LIST_HEAD(&ocus->ocus_conns);
94         file->private_data = ocus;
95
96         MOD_INC_USE_COUNT;
97         RETURN(0);
98 }
99
100 static int
101 obd_class_add_user_conn (struct obd_class_user_state *ocus,
102                          struct lustre_handle *conn)
103 {
104         struct obd_class_user_conn *c;
105
106         /* NB holding obd_conf_sem */
107
108         OBD_ALLOC (c, sizeof (*c));
109         if (ocus == NULL)
110                 return (-ENOMEM);
111
112         c->ocuc_conn = *conn;
113         list_add (&c->ocuc_chain, &ocus->ocus_conns);
114         return (0);
115 }
116
117 static void
118 obd_class_remove_user_conn (struct obd_class_user_state *ocus,
119                             struct lustre_handle *conn)
120 {
121         struct list_head *e;
122         struct obd_class_user_conn *c;
123
124         /* NB holding obd_conf_sem or last reference */
125
126         list_for_each (e, &ocus->ocus_conns) {
127                 c = list_entry (e, struct obd_class_user_conn, ocuc_chain);
128                 if (!memcmp (conn, &c->ocuc_conn, sizeof (*conn))) {
129                         list_del (&c->ocuc_chain);
130                         OBD_FREE (c, sizeof (*c));
131                         return;
132                 }
133         }
134 }
135
136 /*  closing /dev/obd */
137 static int obd_class_release(struct inode * inode, struct file * file)
138 {
139         struct obd_class_user_state *ocus = file->private_data;
140         struct obd_class_user_conn  *c;
141         ENTRY;
142
143         while (!list_empty (&ocus->ocus_conns)) {
144                 c = list_entry (ocus->ocus_conns.next,
145                                 struct obd_class_user_conn, ocuc_chain);
146                 list_del (&c->ocuc_chain);
147
148                 CDEBUG (D_IOCTL, "Auto-disconnect %p\n", &c->ocuc_conn);
149
150                 down (&obd_conf_sem);
151                 obd_disconnect (&c->ocuc_conn);
152                 up (&obd_conf_sem);
153
154                 OBD_FREE (c, sizeof (*c));
155         }
156
157         OBD_FREE (ocus, sizeof (*ocus));
158
159         MOD_DEC_USE_COUNT;
160         RETURN(0);
161 }
162
163 static inline void obd_data2conn(struct lustre_handle *conn,
164                                  struct obd_ioctl_data *data)
165 {
166         conn->addr = data->ioc_addr;
167         conn->cookie = data->ioc_cookie;
168 }
169
170 static inline void obd_conn2data(struct obd_ioctl_data *data,
171                                  struct lustre_handle *conn)
172 {
173         data->ioc_addr = conn->addr;
174         data->ioc_cookie = conn->cookie;
175 }
176
177 static void forcibly_detach_exports(struct obd_device *obd)
178 {
179         int rc;
180         struct list_head *tmp, *n;
181         struct lustre_handle fake_conn;
182
183         CDEBUG(D_IOCTL, "OBD device %d (%p) has exports, "
184                "disconnecting them", obd->obd_minor, obd);
185         list_for_each_safe(tmp, n, &obd->obd_exports) {
186                 struct obd_export *exp = list_entry(tmp, struct obd_export,
187                                                     exp_obd_chain);
188                 fake_conn.addr = (__u64)(unsigned long)exp;
189                 fake_conn.cookie = exp->exp_cookie;
190                 rc = obd_disconnect(&fake_conn);
191                 if (rc) {
192                         CDEBUG(D_IOCTL, "disconnecting export %p failed: %d\n",
193                                exp, rc);
194                 } else {
195                         CDEBUG(D_IOCTL, "export %p disconnected\n", exp);
196                 }
197         }
198 }
199
200
201 int class_handle_ioctl(struct obd_class_user_state *ocus, unsigned int cmd,
202                        unsigned long arg)
203 {
204         char *buf = NULL;
205         struct obd_ioctl_data *data;
206         struct obd_device *obd = ocus->ocus_current_obd;
207         struct lustre_handle conn;
208         int err = 0, len = 0, serialised = 0;
209         ENTRY;
210
211         if ((cmd & 0xffffff00) == ((int)'T') << 8) /* ignore all tty ioctls */
212                 RETURN(err = -ENOTTY);
213
214         switch (cmd) {
215         case OBD_IOC_BRW_WRITE:
216         case OBD_IOC_BRW_READ:
217         case OBD_IOC_GETATTR:
218         case ECHO_IOC_ENQUEUE:
219         case ECHO_IOC_CANCEL:
220                 break;
221         default:
222                 down(&obd_conf_sem);
223                 serialised = 1;
224                 break;
225         }
226
227         CDEBUG(D_IOCTL, "cmd = %x, obd = %p\n", cmd, obd);
228         if (!obd && cmd != OBD_IOC_DEVICE &&
229             cmd != OBD_IOC_LIST && cmd != OBD_GET_VERSION &&
230             cmd != OBD_IOC_NAME2DEV && cmd != OBD_IOC_NEWDEV &&
231             cmd != OBD_IOC_ADD_UUID && cmd != OBD_IOC_DEL_UUID  &&
232             cmd != OBD_IOC_CLOSE_UUID) {
233                 CERROR("OBD ioctl: No device\n");
234                 GOTO(out, err = -EINVAL);
235         }
236         if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
237                 CERROR("OBD ioctl: data error\n");
238                 GOTO(out, err = -EINVAL);
239         }
240         data = (struct obd_ioctl_data *)buf;
241
242         switch (cmd) {
243         case OBD_IOC_DEVICE: {
244                 CDEBUG(D_IOCTL, "\n");
245                 if (data->ioc_dev >= MAX_OBD_DEVICES || data->ioc_dev < 0) {
246                         CERROR("OBD ioctl: DEVICE insufficient devices\n");
247                         GOTO(out, err=-EINVAL);
248                 }
249                 CDEBUG(D_IOCTL, "device %d\n", data->ioc_dev);
250
251                 ocus->ocus_current_obd = &obd_dev[data->ioc_dev];
252                 GOTO(out, err=0);
253         }
254
255         case OBD_IOC_LIST: {
256                 int i;
257                 char *buf2 = data->ioc_bulk;
258                 int remains = data->ioc_inllen1;
259
260                 if (!data->ioc_inlbuf1) {
261                         CERROR("No buffer passed!\n");
262                         GOTO(out, err=-EINVAL);
263                 }
264
265
266                 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
267                         int l;
268                         char *status;
269                         struct obd_device *obd = &obd_dev[i];
270
271                         if (!obd->obd_type)
272                                 continue;
273                         if (obd->obd_flags & OBD_SET_UP)
274                                 status = "UP";
275                         else if (obd->obd_flags & OBD_ATTACHED)
276                                 status = "AT";
277                         else
278                                 status = "-";
279                         l = snprintf(buf2, remains, "%2d %s %s %s %s %d\n",
280                                      i, status, obd->obd_type->typ_name,
281                                      obd->obd_name, obd->obd_uuid.uuid,
282                                      obd->obd_type->typ_refcnt);
283                         buf2 +=l;
284                         remains -=l;
285                         if (remains <= 0) {
286                                 CERROR("not enough space for device listing\n");
287                                 break;
288                         }
289                 }
290
291                 err = copy_to_user((void *)arg, data, len);
292                 if (err)
293                         err = -EFAULT;
294                 GOTO(out, err);
295         }
296
297         case OBD_GET_VERSION:
298                 if (!data->ioc_inlbuf1) {
299                         CERROR("No buffer passed in ioctl\n");
300                         GOTO(out, err = -EINVAL);
301                 }
302
303                 if (strlen(BUILD_VERSION) + 1 > data->ioc_inllen1) {
304                         CERROR("ioctl buffer too small to hold version\n");
305                         GOTO(out, err = -EINVAL);
306                 }
307
308                 memcpy(data->ioc_bulk, BUILD_VERSION,
309                        strlen(BUILD_VERSION) + 1);
310
311                 err = copy_to_user((void *)arg, data, len);
312                 if (err)
313                         err = -EFAULT;
314                 GOTO(out, err);
315
316         case OBD_IOC_NAME2DEV: {
317                 /* Resolve a device name.  This does not change the
318                  * currently selected device.
319                  */
320                 int dev;
321
322                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1 ) {
323                         CERROR("No name passed,!\n");
324                         GOTO(out, err=-EINVAL);
325                 }
326                 if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
327                         CERROR("Name not nul terminated!\n");
328                         GOTO(out, err=-EINVAL);
329                 }
330
331                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
332                 dev = class_name2dev(data->ioc_inlbuf1);
333                 data->ioc_dev = dev;
334                 if (dev == -1) {
335                         CDEBUG(D_IOCTL, "No device for name %s!\n",
336                                data->ioc_inlbuf1);
337                         GOTO(out, err=-EINVAL);
338                 }
339
340                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
341                        dev);
342                 err = copy_to_user((void *)arg, data, sizeof(*data));
343                 if (err)
344                         err = -EFAULT;
345                 GOTO(out, err);
346         }
347
348         case OBD_IOC_UUID2DEV: {
349                 /* Resolve a device uuid.  This does not change the
350                  * currently selected device.
351                  */
352                 int dev;
353                 struct obd_uuid uuid;
354
355                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
356                         CERROR("No UUID passed!\n");
357                         GOTO(out, err=-EINVAL);
358                 }
359                 if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
360                         CERROR("Name not nul terminated!\n");
361                         GOTO(out, err=-EINVAL);
362                 }
363
364                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
365                 obd_str2uuid(&uuid, data->ioc_inlbuf1);
366                 dev = class_uuid2dev(&uuid);
367                 data->ioc_dev = dev;
368                 if (dev == -1) {
369                         CDEBUG(D_IOCTL, "No device for name %s!\n",
370                                data->ioc_inlbuf1);
371                         GOTO(out, err=-EINVAL);
372                 }
373
374                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
375                        dev);
376                 err = copy_to_user((void *)arg, data, sizeof(*data));
377                 if (err)
378                         err = -EFAULT;
379                 GOTO(out, err);
380         }
381
382         case OBD_IOC_NEWDEV: {
383                 int dev = -1;
384                 int i;
385
386                 ocus->ocus_current_obd = NULL;
387                 for (i = 0 ; i < MAX_OBD_DEVICES ; i++) {
388                         struct obd_device *obd = &obd_dev[i];
389                         if (!obd->obd_type) {
390                                 ocus->ocus_current_obd = obd;
391                                 dev = i;
392                                 break;
393                         }
394                 }
395
396
397                 data->ioc_dev = dev;
398                 if (dev == -1)
399                         GOTO(out, err=-EINVAL);
400
401                 err = copy_to_user((void *)arg, data, sizeof(*data));
402                 if (err)
403                         err = -EFAULT;
404                 GOTO(out, err);
405         }
406
407         case OBD_IOC_ATTACH: {
408                 struct obd_type *type;
409                 int minor, len;
410
411                 /* have we attached a type to this device */
412                 if (obd->obd_flags & OBD_ATTACHED || obd->obd_type) {
413                         CERROR("OBD: Device %d already typed as %s.\n",
414                                obd->obd_minor, MKSTR(obd->obd_type->typ_name));
415                         GOTO(out, err = -EBUSY);
416                 }
417
418                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
419                         CERROR("No type passed!\n");
420                         GOTO(out, err = -EINVAL);
421                 }
422                 if (data->ioc_inlbuf1[data->ioc_inllen1-1] !=0) {
423                         CERROR("Type not nul terminated!\n");
424                         GOTO(out, err = -EINVAL);
425                 }
426                 if (!data->ioc_inllen2 || !data->ioc_inlbuf2) {
427                         CERROR("No name passed!\n");
428                         GOTO(out, err = -EINVAL);
429                 }
430                 CDEBUG(D_IOCTL, "attach type %s name: %s uuid: %s\n",
431                        MKSTR(data->ioc_inlbuf1),
432                        MKSTR(data->ioc_inlbuf2), MKSTR(data->ioc_inlbuf3));
433
434                 /* find the type */
435                 type = class_get_type(data->ioc_inlbuf1);
436                 if (!type) {
437                         CERROR("OBD: unknown type dev %d\n", obd->obd_minor);
438                         GOTO(out, err = -EINVAL);
439                 }
440
441                 minor = obd->obd_minor;
442                 memset(obd, 0, sizeof(*obd));
443                 obd->obd_minor = minor;
444                 obd->obd_type = type;
445                 INIT_LIST_HEAD(&obd->obd_exports);
446                 INIT_LIST_HEAD(&obd->obd_imports);
447                 spin_lock_init(&obd->obd_dev_lock);
448
449                 /* XXX belong ins setup not attach  */
450                 /* recovery data */
451                 spin_lock_init(&obd->obd_processing_task_lock);
452                 init_waitqueue_head(&obd->obd_next_transno_waitq);
453                 INIT_LIST_HEAD(&obd->obd_recovery_queue);
454                 INIT_LIST_HEAD(&obd->obd_delayed_reply_queue);
455
456                 len = strlen(data->ioc_inlbuf2) + 1;
457                 OBD_ALLOC(obd->obd_name, len);
458                 if (!obd->obd_name) {
459                         class_put_type(obd->obd_type);
460                         obd->obd_type = NULL;
461                         GOTO(out, err = -ENOMEM);
462                 }
463                 memcpy(obd->obd_name, data->ioc_inlbuf2, len);
464
465                 if (data->ioc_inlbuf3) {
466                         int len = strlen(data->ioc_inlbuf3);
467                         if (len >= sizeof(obd->obd_uuid)) {
468                                 CERROR("uuid must be < "LPSZ" bytes long\n",
469                                        sizeof(obd->obd_uuid));
470                                 if (obd->obd_name)
471                                         OBD_FREE(obd->obd_name,
472                                                  strlen(obd->obd_name) + 1);
473                                 class_put_type(obd->obd_type);
474                                 obd->obd_type = NULL;
475                                 GOTO(out, err=-EINVAL);
476                         }
477                         memcpy(obd->obd_uuid.uuid, data->ioc_inlbuf3, len);
478                 }
479                 /* do the attach */
480                 if (OBP(obd, attach))
481                         err = OBP(obd,attach)(obd, sizeof(*data), data);
482                 if (err) {
483                         if(data->ioc_inlbuf2)
484                                 OBD_FREE(obd->obd_name,
485                                          strlen(obd->obd_name) + 1);
486                         class_put_type(obd->obd_type);
487                         obd->obd_type = NULL;
488                 } else {
489                         obd->obd_flags |= OBD_ATTACHED;
490
491                         type->typ_refcnt++;
492                         CDEBUG(D_IOCTL, "OBD: dev %d attached type %s\n",
493                                obd->obd_minor, data->ioc_inlbuf1);
494                 }
495
496                 GOTO(out, err);
497         }
498
499         case OBD_IOC_DETACH: {
500                 ENTRY;
501                 if (obd->obd_flags & OBD_SET_UP) {
502                         CERROR("OBD device %d still set up\n", obd->obd_minor);
503                         GOTO(out, err=-EBUSY);
504                 }
505                 if (!(obd->obd_flags & OBD_ATTACHED) ) {
506                         CERROR("OBD device %d not attached\n", obd->obd_minor);
507                         GOTO(out, err=-ENODEV);
508                 }
509                 if (OBP(obd, detach))
510                         err = OBP(obd,detach)(obd);
511
512                 if (obd->obd_name) {
513                         OBD_FREE(obd->obd_name, strlen(obd->obd_name)+1);
514                         obd->obd_name = NULL;
515                 }
516
517                 obd->obd_flags &= ~OBD_ATTACHED;
518                 obd->obd_type->typ_refcnt--;
519                 class_put_type(obd->obd_type);
520                 obd->obd_type = NULL;
521                 GOTO(out, err = 0);
522         }
523
524         case OBD_IOC_SETUP: {
525                 /* have we attached a type to this device? */
526                 if (!(obd->obd_flags & OBD_ATTACHED)) {
527                         CERROR("Device %d not attached\n", obd->obd_minor);
528                         GOTO(out, err=-ENODEV);
529                 }
530
531                 /* has this been done already? */
532                 if ( obd->obd_flags & OBD_SET_UP ) {
533                         CERROR("Device %d already setup (type %s)\n",
534                                obd->obd_minor, obd->obd_type->typ_name);
535                         GOTO(out, err=-EBUSY);
536                 }
537
538                 if ( OBT(obd) && OBP(obd, setup) )
539                         err = obd_setup(obd, sizeof(*data), data);
540
541                 if (!err) {
542                         obd->obd_type->typ_refcnt++;
543                         obd->obd_flags |= OBD_SET_UP;
544                 }
545
546                 GOTO(out, err);
547         }
548         case OBD_IOC_CLEANUP: {
549                 /* have we attached a type to this device? */
550                 if (!(obd->obd_flags & OBD_ATTACHED)) {
551                         CERROR("Device %d not attached\n", obd->obd_minor);
552                         GOTO(out, err=-ENODEV);
553                 }
554                 if (!list_empty(&obd->obd_exports)) {
555                         if (!data->ioc_inlbuf1 || data->ioc_inlbuf1[0] != 'F') {
556                                 CERROR("OBD device %d (%p) has exports\n",
557                                        obd->obd_minor, obd);
558                                 GOTO(out, err = -EBUSY);
559                         }
560                         forcibly_detach_exports(obd);
561                 }
562                 if (OBT(obd) && OBP(obd, cleanup))
563                         err = obd_cleanup(obd);
564
565                 if (!err) {
566                         obd->obd_flags &= ~OBD_SET_UP;
567                         obd->obd_type->typ_refcnt--;
568                 }
569                 GOTO(out, err);
570         }
571
572         case OBD_IOC_CONNECT: {
573                 struct obd_uuid cluuid = { "OBD_CLASS_UUID" };
574                 obd_data2conn(&conn, data);
575
576                 err = obd_connect(&conn, obd, &cluuid, NULL, NULL);
577
578                 CDEBUG(D_IOCTL, "assigned export "LPX64"\n", conn.addr);
579                 obd_conn2data(data, &conn);
580                 if (err)
581                         GOTO(out, err);
582
583                 err = obd_class_add_user_conn (ocus, &conn);
584                 if (err != 0) {
585                         obd_disconnect (&conn);
586                         GOTO (out, err);
587                 }
588
589                 err = copy_to_user((void *)arg, data, sizeof(*data));
590                 if (err != 0) {
591                         obd_class_remove_user_conn (ocus, &conn);
592                         obd_disconnect (&conn);
593                         GOTO (out, err=-EFAULT);
594                 }
595                 GOTO(out, err);
596         }
597
598         case OBD_IOC_DISCONNECT: {
599                 obd_data2conn(&conn, data);
600                 obd_class_remove_user_conn (ocus, &conn);
601                 err = obd_disconnect(&conn);
602                 GOTO(out, err);
603         }
604
605         case OBD_IOC_NO_TRANSNO: {
606                 if (!(obd->obd_flags & OBD_ATTACHED)) {
607                         CERROR("Device %d not attached\n", obd->obd_minor);
608                         GOTO(out, err=-ENODEV);
609                 }
610                 CDEBUG(D_IOCTL,
611                        "disabling committed-transno notifications on %d\n",
612                        obd->obd_minor);
613                 obd->obd_flags |= OBD_NO_TRANSNO;
614                 GOTO(out, err = 0);
615         }
616
617         case OBD_IOC_CLOSE_UUID: {
618                 struct lustre_peer peer;
619                 CDEBUG(D_IOCTL, "closing all connections to uuid %s\n",
620                        data->ioc_inlbuf1);
621                 lustre_uuid_to_peer(data->ioc_inlbuf1, &peer);
622                 GOTO(out, err = 0);
623         }
624         case OBD_IOC_ADD_UUID: {
625                 CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid "LPX64
626                        ", nal %d\n", data->ioc_inlbuf1, data->ioc_nid,
627                        data->ioc_nal);
628
629                 err = class_add_uuid(data->ioc_inlbuf1, data->ioc_nid,
630                                      data->ioc_nal);
631                 GOTO(out, err);
632         }
633         case OBD_IOC_DEL_UUID: {
634                 CDEBUG(D_IOCTL, "removing mappings for uuid %s\n",
635                        data->ioc_inlbuf1 == NULL ? "<all uuids>" :
636                        data->ioc_inlbuf1);
637
638                 err = class_del_uuid(data->ioc_inlbuf1);
639                 GOTO(out, err);
640         }
641         default: { 
642                 // obd_data2conn(&conn, data);
643                 struct obd_class_user_conn *oconn = list_entry(ocus->ocus_conns.next, struct obd_class_user_conn, ocuc_chain);
644                 err = obd_iocontrol(cmd, &oconn->ocuc_conn, len, data, NULL);
645                 if (err)
646                         GOTO(out, err);
647
648                 err = copy_to_user((void *)arg, data, len);
649                 if (err)
650                         err = -EFAULT;
651                 GOTO(out, err);
652         }
653         }
654
655  out:
656         if (buf)
657                 OBD_FREE(buf, len);
658         if (serialised)
659                 up(&obd_conf_sem);
660         RETURN(err);
661 } /* obd_class_ioctl */
662
663
664
665 #define OBD_MINOR 241
666 #ifdef __KERNEL__
667 /* to control /dev/obd */
668 static int obd_class_ioctl(struct inode *inode, struct file *filp,
669                            unsigned int cmd, unsigned long arg)
670 {
671         return class_handle_ioctl(filp->private_data, cmd, arg);
672 }
673
674 /* declare character device */
675 static struct file_operations obd_psdev_fops = {
676         ioctl:   obd_class_ioctl,       /* ioctl */
677         open:    obd_class_open,        /* open */
678         release: obd_class_release,     /* release */
679 };
680
681 /* modules setup */
682 static struct miscdevice obd_psdev = {
683         OBD_MINOR,
684         "obd_psdev",
685         &obd_psdev_fops
686 };
687 #else
688 void *obd_psdev = NULL;
689 #endif
690
691 void (*class_signal_connection_failure)(struct ptlrpc_connection *);
692
693 #ifdef CONFIG_HIGHMEM
694 /* Allow at most 3/4 of the kmap mappings to be consumed by vector I/O
695  * requests.  This avoids deadlocks on servers which have a lot of clients
696  * doing vector I/O.  We don't need to do this for non-vector I/O requests
697  * because singleton requests will just block on the kmap itself and never
698  * deadlock waiting for additional kmaps to complete.
699  *
700  * If we are a "server" task, we can have at most a single reservation
701  * in excess of the maximum.  This avoids a deadlock when multiple client
702  * threads are on the same machine as the server threads, and the clients
703  * have consumed all of the available mappings.  As long as a single server
704  * thread is can make progress, we are guaranteed to avoid deadlock.
705  */
706 #define OBD_KMAP_MAX (LAST_PKMAP * 3 / 4)
707 static atomic_t obd_kmap_count = ATOMIC_INIT(OBD_KMAP_MAX);
708 static DECLARE_WAIT_QUEUE_HEAD(obd_kmap_waitq);
709
710 void obd_kmap_get(int count, int server)
711 {
712         //CERROR("getting %d kmap counts (%d/%d)\n", count,
713         //       atomic_read(&obd_kmap_count), OBD_KMAP_MAX);
714         if (count == 1)
715                 atomic_dec(&obd_kmap_count);
716         else while (atomic_add_negative(-count, &obd_kmap_count)) {
717                 struct l_wait_info lwi = { 0 };
718                 static long next_show = 0;
719                 static int skipped = 0;
720
721                 if (server && atomic_read(&obd_kmap_count) >= -PTL_MD_MAX_IOV)
722                         break;
723
724                 CDEBUG(D_OTHER, "negative kmap reserved count: %d\n",
725                        atomic_read(&obd_kmap_count));
726                 atomic_add(count, &obd_kmap_count);
727
728                 if (time_after(jiffies, next_show)) {
729                         CERROR("blocking %s (and %d others) for kmaps\n",
730                                current->comm, skipped);
731                         next_show = jiffies + 5*HZ;
732                         skipped = 0;
733                 } else
734                         skipped++;
735                 l_wait_event(obd_kmap_waitq,
736                              atomic_read(&obd_kmap_count) >= count, &lwi);
737         }
738 }
739
740 void obd_kmap_put(int count)
741 {
742         atomic_add(count, &obd_kmap_count);
743         /* Wake up sleepers.  Sadly, this wakes up all of the tasks at once.
744          * We could have something smarter here like:
745         while (atomic_read(&obd_kmap_count) > 0)
746                 wake_up_nr(obd_kmap_waitq, 1);
747         although we would need to set somewhere (probably obd_class_init):
748         obd_kmap_waitq.flags |= WQ_FLAG_EXCLUSIVE;
749         For now the wait_event() condition will handle this OK I believe.
750          */
751         if (atomic_read(&obd_kmap_count) > 0)
752                 wake_up(&obd_kmap_waitq);
753 }
754
755 EXPORT_SYMBOL(obd_kmap_get);
756 EXPORT_SYMBOL(obd_kmap_put);
757 #endif
758
759 EXPORT_SYMBOL(obd_dev);
760 EXPORT_SYMBOL(obdo_cachep);
761 EXPORT_SYMBOL(obd_memory);
762 EXPORT_SYMBOL(obd_memmax);
763 EXPORT_SYMBOL(obd_fail_loc);
764 EXPORT_SYMBOL(obd_timeout);
765 EXPORT_SYMBOL(obd_recovery_upcall);
766 EXPORT_SYMBOL(obd_sync_filter);
767 EXPORT_SYMBOL(ptlrpc_put_connection_superhack);
768 EXPORT_SYMBOL(ptlrpc_abort_inflight_superhack);
769 EXPORT_SYMBOL(proc_lustre_root);
770
771 EXPORT_SYMBOL(class_register_type);
772 EXPORT_SYMBOL(class_unregister_type);
773 EXPORT_SYMBOL(class_get_type);
774 EXPORT_SYMBOL(class_put_type);
775 EXPORT_SYMBOL(class_name2dev);
776 EXPORT_SYMBOL(class_uuid2dev);
777 EXPORT_SYMBOL(class_uuid2obd);
778 EXPORT_SYMBOL(class_new_export);
779 EXPORT_SYMBOL(class_destroy_export);
780 EXPORT_SYMBOL(class_connect);
781 EXPORT_SYMBOL(class_conn2export);
782 EXPORT_SYMBOL(class_conn2obd);
783 EXPORT_SYMBOL(class_conn2cliimp);
784 EXPORT_SYMBOL(class_conn2ldlmimp);
785 EXPORT_SYMBOL(class_disconnect);
786 EXPORT_SYMBOL(class_disconnect_all);
787 EXPORT_SYMBOL(class_uuid_unparse);
788 EXPORT_SYMBOL(lustre_uuid_to_peer);
789
790 EXPORT_SYMBOL(class_signal_connection_failure);
791
792 EXPORT_SYMBOL(class_handle_hash);
793 EXPORT_SYMBOL(class_handle_unhash);
794 EXPORT_SYMBOL(class_handle2object);
795
796 #ifdef __KERNEL__
797 static int __init init_obdclass(void)
798 #else
799 int init_obdclass(void)
800 #endif
801 {
802         struct obd_device *obd;
803         int err;
804         int i;
805
806         printk(KERN_INFO "OBD class driver Build Version: " BUILD_VERSION
807                       ", info@clusterfs.com\n");
808
809         class_init_uuidlist();
810         class_handle_init();
811
812         sema_init(&obd_conf_sem, 1);
813         INIT_LIST_HEAD(&obd_types);
814
815         if ((err = misc_register(&obd_psdev))) {
816                 CERROR("cannot register %d err %d\n", OBD_MINOR, err);
817                 return err;
818         }
819
820         /* This struct is already zerod for us (static global) */
821         for (i = 0, obd = obd_dev; i < MAX_OBD_DEVICES; i++, obd++)
822                 obd->obd_minor = i;
823
824         err = obd_init_caches();
825         if (err)
826                 return err;
827
828 #ifdef __KERNEL__
829         obd_sysctl_init();
830 #endif
831
832 #ifdef LPROCFS
833         proc_lustre_root = proc_mkdir("lustre", proc_root_fs);
834         if (!proc_lustre_root)
835                 printk(KERN_ERR "error registering /proc/fs/lustre\n");
836 #else
837         proc_lustre_root = NULL;
838 #endif
839         return 0;
840 }
841
842 #ifdef __KERNEL__
843 static void __exit cleanup_obdclass(void)
844 #else
845 static void cleanup_obdclass(void)
846 #endif
847 {
848         int i;
849         ENTRY;
850
851         misc_deregister(&obd_psdev);
852         for (i = 0; i < MAX_OBD_DEVICES; i++) {
853                 struct obd_device *obd = &obd_dev[i];
854                 if (obd->obd_type && (obd->obd_flags & OBD_SET_UP) &&
855                     OBT(obd) && OBP(obd, detach)) {
856                         /* XXX should this call generic detach otherwise? */
857                         OBP(obd, detach)(obd);
858                 }
859         }
860
861         obd_cleanup_caches();
862 #ifdef __KERNEL__
863         obd_sysctl_clean();
864 #endif
865         if (proc_lustre_root) {
866                 lprocfs_remove(proc_lustre_root);
867                 proc_lustre_root = NULL;
868         }
869
870         class_handle_cleanup();
871         class_exit_uuidlist();
872
873         CERROR("obd mem max: %d leaked: %d\n", obd_memmax,
874                atomic_read(&obd_memory));
875         EXIT;
876 }
877
878 /* Check that we're building against the appropriate version of the Lustre
879  * kernel patch */
880 #ifdef __KERNEL__
881 #include <linux/lustre_version.h>
882 #define LUSTRE_SOURCE_VERSION 13
883 #if (LUSTRE_KERNEL_VERSION < LUSTRE_SOURCE_VERSION)
884 # error Cannot continue: Your Lustre kernel patch is older than the sources
885 #elif (LUSTRE_KERNEL_VERSION > LUSTRE_SOURCE_VERSION)
886 # error Cannot continue: Your Lustre sources are older than the kernel patch
887 #endif
888 #else
889 #warning "Lib Lustre - no versioning information"
890 #endif
891
892 #ifdef __KERNEL__
893 MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
894 MODULE_DESCRIPTION("Lustre Class Driver Build Version: " BUILD_VERSION);
895 MODULE_LICENSE("GPL");
896
897 module_init(init_obdclass);
898 module_exit(cleanup_obdclass);
899 #endif