Merge remote-tracking branches 'regulator/fix/da9211', 'regulator/fix/ltc3589' and...
[sfrench/cifs-2.6.git] / drivers / staging / lustre / lustre / obdclass / class_obd.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2011, 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #define DEBUG_SUBSYSTEM S_CLASS
38 # include <linux/atomic.h>
39
40 #include "../include/obd_support.h"
41 #include "../include/obd_class.h"
42 #include "../../include/linux/lnet/lnetctl.h"
43 #include "../include/lustre_debug.h"
44 #include "../include/lprocfs_status.h"
45 #include "../include/lustre/lustre_build_version.h"
46 #include <linux/list.h>
47 #include "../include/cl_object.h"
48 #include "llog_internal.h"
49
50
51 struct obd_device *obd_devs[MAX_OBD_DEVICES];
52 EXPORT_SYMBOL(obd_devs);
53 struct list_head obd_types;
54 DEFINE_RWLOCK(obd_dev_lock);
55
56 __u64 obd_max_pages = 0;
57 EXPORT_SYMBOL(obd_max_pages);
58 __u64 obd_max_alloc = 0;
59 EXPORT_SYMBOL(obd_max_alloc);
60 __u64 obd_alloc;
61 EXPORT_SYMBOL(obd_alloc);
62 __u64 obd_pages;
63 EXPORT_SYMBOL(obd_pages);
64 DEFINE_SPINLOCK(obd_updatemax_lock);
65
66 /* The following are visible and mutable through /proc/sys/lustre/. */
67 unsigned int obd_alloc_fail_rate = 0;
68 EXPORT_SYMBOL(obd_alloc_fail_rate);
69 unsigned int obd_debug_peer_on_timeout;
70 EXPORT_SYMBOL(obd_debug_peer_on_timeout);
71 unsigned int obd_dump_on_timeout;
72 EXPORT_SYMBOL(obd_dump_on_timeout);
73 unsigned int obd_dump_on_eviction;
74 EXPORT_SYMBOL(obd_dump_on_eviction);
75 unsigned int obd_max_dirty_pages = 256;
76 EXPORT_SYMBOL(obd_max_dirty_pages);
77 atomic_t obd_dirty_pages;
78 EXPORT_SYMBOL(obd_dirty_pages);
79 unsigned int obd_timeout = OBD_TIMEOUT_DEFAULT;   /* seconds */
80 EXPORT_SYMBOL(obd_timeout);
81 unsigned int ldlm_timeout = LDLM_TIMEOUT_DEFAULT; /* seconds */
82 EXPORT_SYMBOL(ldlm_timeout);
83 unsigned int obd_timeout_set;
84 EXPORT_SYMBOL(obd_timeout_set);
85 unsigned int ldlm_timeout_set;
86 EXPORT_SYMBOL(ldlm_timeout_set);
87 /* Adaptive timeout defs here instead of ptlrpc module for /proc/sys/ access */
88 unsigned int at_min = 0;
89 EXPORT_SYMBOL(at_min);
90 unsigned int at_max = 600;
91 EXPORT_SYMBOL(at_max);
92 unsigned int at_history = 600;
93 EXPORT_SYMBOL(at_history);
94 int at_early_margin = 5;
95 EXPORT_SYMBOL(at_early_margin);
96 int at_extra = 30;
97 EXPORT_SYMBOL(at_extra);
98
99 atomic_t obd_dirty_transit_pages;
100 EXPORT_SYMBOL(obd_dirty_transit_pages);
101
102 char obd_jobid_var[JOBSTATS_JOBID_VAR_MAX_LEN + 1] = JOBSTATS_DISABLE;
103 EXPORT_SYMBOL(obd_jobid_var);
104
105 char obd_jobid_node[JOBSTATS_JOBID_SIZE + 1];
106
107 /* Get jobid of current process from stored variable or calculate
108  * it from pid and user_id.
109  *
110  * Historically this was also done by reading the environment variable
111  * stored in between the "env_start" & "env_end" of task struct.
112  * This is now deprecated.
113  */
114 int lustre_get_jobid(char *jobid)
115 {
116         memset(jobid, 0, JOBSTATS_JOBID_SIZE);
117         /* Jobstats isn't enabled */
118         if (strcmp(obd_jobid_var, JOBSTATS_DISABLE) == 0)
119                 return 0;
120
121         /* Use process name + fsuid as jobid */
122         if (strcmp(obd_jobid_var, JOBSTATS_PROCNAME_UID) == 0) {
123                 snprintf(jobid, JOBSTATS_JOBID_SIZE, "%s.%u",
124                          current_comm(),
125                          from_kuid(&init_user_ns, current_fsuid()));
126                 return 0;
127         }
128
129         /* Whole node dedicated to single job */
130         if (strcmp(obd_jobid_var, JOBSTATS_NODELOCAL) == 0) {
131                 strcpy(jobid, obd_jobid_node);
132                 return 0;
133         }
134
135         return -ENOENT;
136 }
137 EXPORT_SYMBOL(lustre_get_jobid);
138
139 int obd_alloc_fail(const void *ptr, const char *name, const char *type,
140                    size_t size, const char *file, int line)
141 {
142         if (ptr == NULL ||
143             (cfs_rand() & OBD_ALLOC_FAIL_MASK) < obd_alloc_fail_rate) {
144                 CERROR("%s%salloc of %s (%llu bytes) failed at %s:%d\n",
145                        ptr ? "force " :"", type, name, (__u64)size, file,
146                        line);
147                 CERROR("%llu total bytes and %llu total pages "
148                        "(%llu bytes) allocated by Lustre, "
149                        "%d total bytes by LNET\n",
150                        obd_memory_sum(),
151                        obd_pages_sum() << PAGE_CACHE_SHIFT,
152                        obd_pages_sum(),
153                         atomic_read(&libcfs_kmemory));
154                 return 1;
155         }
156         return 0;
157 }
158 EXPORT_SYMBOL(obd_alloc_fail);
159
160 static inline void obd_data2conn(struct lustre_handle *conn,
161                                  struct obd_ioctl_data *data)
162 {
163         memset(conn, 0, sizeof(*conn));
164         conn->cookie = data->ioc_cookie;
165 }
166
167 static inline void obd_conn2data(struct obd_ioctl_data *data,
168                                  struct lustre_handle *conn)
169 {
170         data->ioc_cookie = conn->cookie;
171 }
172
173 int class_resolve_dev_name(__u32 len, const char *name)
174 {
175         int rc;
176         int dev;
177
178         if (!len || !name) {
179                 CERROR("No name passed,!\n");
180                 GOTO(out, rc = -EINVAL);
181         }
182         if (name[len - 1] != 0) {
183                 CERROR("Name not nul terminated!\n");
184                 GOTO(out, rc = -EINVAL);
185         }
186
187         CDEBUG(D_IOCTL, "device name %s\n", name);
188         dev = class_name2dev(name);
189         if (dev == -1) {
190                 CDEBUG(D_IOCTL, "No device for name %s!\n", name);
191                 GOTO(out, rc = -EINVAL);
192         }
193
194         CDEBUG(D_IOCTL, "device name %s, dev %d\n", name, dev);
195         rc = dev;
196
197 out:
198         return rc;
199 }
200
201 int class_handle_ioctl(unsigned int cmd, unsigned long arg)
202 {
203         char *buf = NULL;
204         struct obd_ioctl_data *data;
205         struct libcfs_debug_ioctl_data *debug_data;
206         struct obd_device *obd = NULL;
207         int err = 0, len = 0;
208
209         /* only for debugging */
210         if (cmd == LIBCFS_IOC_DEBUG_MASK) {
211                 debug_data = (struct libcfs_debug_ioctl_data*)arg;
212                 libcfs_subsystem_debug = debug_data->subs;
213                 libcfs_debug = debug_data->debug;
214                 return 0;
215         }
216
217         CDEBUG(D_IOCTL, "cmd = %x\n", cmd);
218         if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
219                 CERROR("OBD ioctl: data error\n");
220                 return -EINVAL;
221         }
222         data = (struct obd_ioctl_data *)buf;
223
224         switch (cmd) {
225         case OBD_IOC_PROCESS_CFG: {
226                 struct lustre_cfg *lcfg;
227
228                 if (!data->ioc_plen1 || !data->ioc_pbuf1) {
229                         CERROR("No config buffer passed!\n");
230                         GOTO(out, err = -EINVAL);
231                 }
232                 OBD_ALLOC(lcfg, data->ioc_plen1);
233                 if (lcfg == NULL)
234                         GOTO(out, err = -ENOMEM);
235                 err = copy_from_user(lcfg, data->ioc_pbuf1,
236                                          data->ioc_plen1);
237                 if (!err)
238                         err = lustre_cfg_sanity_check(lcfg, data->ioc_plen1);
239                 if (!err)
240                         err = class_process_config(lcfg);
241
242                 OBD_FREE(lcfg, data->ioc_plen1);
243                 GOTO(out, err);
244         }
245
246         case OBD_GET_VERSION:
247                 if (!data->ioc_inlbuf1) {
248                         CERROR("No buffer passed in ioctl\n");
249                         GOTO(out, err = -EINVAL);
250                 }
251
252                 if (strlen(BUILD_VERSION) + 1 > data->ioc_inllen1) {
253                         CERROR("ioctl buffer too small to hold version\n");
254                         GOTO(out, err = -EINVAL);
255                 }
256
257                 memcpy(data->ioc_bulk, BUILD_VERSION,
258                        strlen(BUILD_VERSION) + 1);
259
260                 err = obd_ioctl_popdata((void *)arg, data, len);
261                 if (err)
262                         err = -EFAULT;
263                 GOTO(out, err);
264
265         case OBD_IOC_NAME2DEV: {
266                 /* Resolve a device name.  This does not change the
267                  * currently selected device.
268                  */
269                 int dev;
270
271                 dev = class_resolve_dev_name(data->ioc_inllen1,
272                                              data->ioc_inlbuf1);
273                 data->ioc_dev = dev;
274                 if (dev < 0)
275                         GOTO(out, err = -EINVAL);
276
277                 err = obd_ioctl_popdata((void *)arg, data, sizeof(*data));
278                 if (err)
279                         err = -EFAULT;
280                 GOTO(out, err);
281         }
282
283         case OBD_IOC_UUID2DEV: {
284                 /* Resolve a device uuid.  This does not change the
285                  * currently selected device.
286                  */
287                 int dev;
288                 struct obd_uuid uuid;
289
290                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
291                         CERROR("No UUID passed!\n");
292                         GOTO(out, err = -EINVAL);
293                 }
294                 if (data->ioc_inlbuf1[data->ioc_inllen1 - 1] != 0) {
295                         CERROR("UUID not NUL terminated!\n");
296                         GOTO(out, err = -EINVAL);
297                 }
298
299                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
300                 obd_str2uuid(&uuid, data->ioc_inlbuf1);
301                 dev = class_uuid2dev(&uuid);
302                 data->ioc_dev = dev;
303                 if (dev == -1) {
304                         CDEBUG(D_IOCTL, "No device for UUID %s!\n",
305                                data->ioc_inlbuf1);
306                         GOTO(out, err = -EINVAL);
307                 }
308
309                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
310                        dev);
311                 err = obd_ioctl_popdata((void *)arg, data, sizeof(*data));
312                 if (err)
313                         err = -EFAULT;
314                 GOTO(out, err);
315         }
316
317         case OBD_IOC_CLOSE_UUID: {
318                 CDEBUG(D_IOCTL, "closing all connections to uuid %s (NOOP)\n",
319                        data->ioc_inlbuf1);
320                 GOTO(out, err = 0);
321         }
322
323         case OBD_IOC_GETDEVICE: {
324                 int     index = data->ioc_count;
325                 char    *status, *str;
326
327                 if (!data->ioc_inlbuf1) {
328                         CERROR("No buffer passed in ioctl\n");
329                         GOTO(out, err = -EINVAL);
330                 }
331                 if (data->ioc_inllen1 < 128) {
332                         CERROR("ioctl buffer too small to hold version\n");
333                         GOTO(out, err = -EINVAL);
334                 }
335
336                 obd = class_num2obd(index);
337                 if (!obd)
338                         GOTO(out, err = -ENOENT);
339
340                 if (obd->obd_stopping)
341                         status = "ST";
342                 else if (obd->obd_set_up)
343                         status = "UP";
344                 else if (obd->obd_attached)
345                         status = "AT";
346                 else
347                         status = "--";
348                 str = (char *)data->ioc_bulk;
349                 snprintf(str, len - sizeof(*data), "%3d %s %s %s %s %d",
350                          (int)index, status, obd->obd_type->typ_name,
351                          obd->obd_name, obd->obd_uuid.uuid,
352                          atomic_read(&obd->obd_refcount));
353                 err = obd_ioctl_popdata((void *)arg, data, len);
354
355                 GOTO(out, err = 0);
356         }
357
358         }
359
360         if (data->ioc_dev == OBD_DEV_BY_DEVNAME) {
361                 if (data->ioc_inllen4 <= 0 || data->ioc_inlbuf4 == NULL)
362                         GOTO(out, err = -EINVAL);
363                 if (strnlen(data->ioc_inlbuf4, MAX_OBD_NAME) >= MAX_OBD_NAME)
364                         GOTO(out, err = -EINVAL);
365                 obd = class_name2obd(data->ioc_inlbuf4);
366         } else if (data->ioc_dev < class_devno_max()) {
367                 obd = class_num2obd(data->ioc_dev);
368         } else {
369                 CERROR("OBD ioctl: No device\n");
370                 GOTO(out, err = -EINVAL);
371         }
372
373         if (obd == NULL) {
374                 CERROR("OBD ioctl : No Device %d\n", data->ioc_dev);
375                 GOTO(out, err = -EINVAL);
376         }
377         LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
378
379         if (!obd->obd_set_up || obd->obd_stopping) {
380                 CERROR("OBD ioctl: device not setup %d \n", data->ioc_dev);
381                 GOTO(out, err = -EINVAL);
382         }
383
384         switch(cmd) {
385         case OBD_IOC_NO_TRANSNO: {
386                 if (!obd->obd_attached) {
387                         CERROR("Device %d not attached\n", obd->obd_minor);
388                         GOTO(out, err = -ENODEV);
389                 }
390                 CDEBUG(D_HA, "%s: disabling committed-transno notification\n",
391                        obd->obd_name);
392                 obd->obd_no_transno = 1;
393                 GOTO(out, err = 0);
394         }
395
396         default: {
397                 err = obd_iocontrol(cmd, obd->obd_self_export, len, data, NULL);
398                 if (err)
399                         GOTO(out, err);
400
401                 err = obd_ioctl_popdata((void *)arg, data, len);
402                 if (err)
403                         err = -EFAULT;
404                 GOTO(out, err);
405         }
406         }
407
408  out:
409         if (buf)
410                 obd_ioctl_freedata(buf, len);
411         return err;
412 } /* class_handle_ioctl */
413
414 extern struct miscdevice obd_psdev;
415
416 #define OBD_INIT_CHECK
417 int obd_init_checks(void)
418 {
419         __u64 u64val, div64val;
420         char buf[64];
421         int len, ret = 0;
422
423         CDEBUG(D_INFO, "LPU64=%s, LPD64=%s, LPX64=%s\n", "%llu", "%lld", "%#llx");
424
425         CDEBUG(D_INFO, "OBD_OBJECT_EOF = %#llx\n", (__u64)OBD_OBJECT_EOF);
426
427         u64val = OBD_OBJECT_EOF;
428         CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
429         if (u64val != OBD_OBJECT_EOF) {
430                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
431                        u64val, (int)sizeof(u64val));
432                 ret = -EINVAL;
433         }
434         len = snprintf(buf, sizeof(buf), "%#llx", u64val);
435         if (len != 18) {
436                 CWARN("LPX64 wrong length! strlen(%s)=%d != 18\n", buf, len);
437                 ret = -EINVAL;
438         }
439
440         div64val = OBD_OBJECT_EOF;
441         CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
442         if (u64val != OBD_OBJECT_EOF) {
443                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
444                        u64val, (int)sizeof(u64val));
445                 ret = -EOVERFLOW;
446         }
447         if (u64val >> 8 != OBD_OBJECT_EOF >> 8) {
448                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
449                        u64val, (int)sizeof(u64val));
450                 return -EOVERFLOW;
451         }
452         if (do_div(div64val, 256) != (u64val & 255)) {
453                 CERROR("do_div(%#llx,256) != %llu\n", u64val, u64val &255);
454                 return -EOVERFLOW;
455         }
456         if (u64val >> 8 != div64val) {
457                 CERROR("do_div(%#llx,256) %llu != %llu\n",
458                        u64val, div64val, u64val >> 8);
459                 return -EOVERFLOW;
460         }
461         len = snprintf(buf, sizeof(buf), "%#llx", u64val);
462         if (len != 18) {
463                 CWARN("LPX64 wrong length! strlen(%s)=%d != 18\n", buf, len);
464                 ret = -EINVAL;
465         }
466         len = snprintf(buf, sizeof(buf), "%llu", u64val);
467         if (len != 20) {
468                 CWARN("LPU64 wrong length! strlen(%s)=%d != 20\n", buf, len);
469                 ret = -EINVAL;
470         }
471         len = snprintf(buf, sizeof(buf), "%lld", u64val);
472         if (len != 2) {
473                 CWARN("LPD64 wrong length! strlen(%s)=%d != 2\n", buf, len);
474                 ret = -EINVAL;
475         }
476         if ((u64val & ~CFS_PAGE_MASK) >= PAGE_CACHE_SIZE) {
477                 CWARN("mask failed: u64val %llu >= %llu\n", u64val,
478                       (__u64)PAGE_CACHE_SIZE);
479                 ret = -EINVAL;
480         }
481
482         return ret;
483 }
484
485 extern spinlock_t obd_types_lock;
486 #if defined (CONFIG_PROC_FS)
487 extern int class_procfs_init(void);
488 extern int class_procfs_clean(void);
489 #else
490 static inline int class_procfs_init(void)
491 { return 0; }
492 static inline int class_procfs_clean(void)
493 { return 0; }
494 #endif
495
496 static int __init init_obdclass(void)
497 {
498         int i, err;
499         int lustre_register_fs(void);
500
501         for (i = CAPA_SITE_CLIENT; i < CAPA_SITE_MAX; i++)
502                 INIT_LIST_HEAD(&capa_list[i]);
503
504         LCONSOLE_INFO("Lustre: Build Version: "BUILD_VERSION"\n");
505
506         spin_lock_init(&obd_types_lock);
507         obd_zombie_impexp_init();
508
509         obd_memory = lprocfs_alloc_stats(OBD_STATS_NUM,
510                                          LPROCFS_STATS_FLAG_NONE |
511                                          LPROCFS_STATS_FLAG_IRQ_SAFE);
512         if (obd_memory == NULL) {
513                 CERROR("kmalloc of 'obd_memory' failed\n");
514                 return -ENOMEM;
515         }
516
517         lprocfs_counter_init(obd_memory, OBD_MEMORY_STAT,
518                              LPROCFS_CNTR_AVGMINMAX,
519                              "memused", "bytes");
520         lprocfs_counter_init(obd_memory, OBD_MEMORY_PAGES_STAT,
521                              LPROCFS_CNTR_AVGMINMAX,
522                              "pagesused", "pages");
523
524         err = obd_init_checks();
525         if (err == -EOVERFLOW)
526                 return err;
527
528         class_init_uuidlist();
529         err = class_handle_init();
530         if (err)
531                 return err;
532
533         INIT_LIST_HEAD(&obd_types);
534
535         err = misc_register(&obd_psdev);
536         if (err) {
537                 CERROR("cannot register %d err %d\n", OBD_DEV_MINOR, err);
538                 return err;
539         }
540
541         /* This struct is already zeroed for us (static global) */
542         for (i = 0; i < class_devno_max(); i++)
543                 obd_devs[i] = NULL;
544
545         /* Default the dirty page cache cap to 1/2 of system memory.
546          * For clients with less memory, a larger fraction is needed
547          * for other purposes (mostly for BGL). */
548         if (totalram_pages <= 512 << (20 - PAGE_CACHE_SHIFT))
549                 obd_max_dirty_pages = totalram_pages / 4;
550         else
551                 obd_max_dirty_pages = totalram_pages / 2;
552
553         err = obd_init_caches();
554         if (err)
555                 return err;
556
557         obd_sysctl_init();
558
559         err = class_procfs_init();
560         if (err)
561                 return err;
562
563         err = lu_global_init();
564         if (err)
565                 return err;
566
567         err = cl_global_init();
568         if (err != 0)
569                 return err;
570
571
572         err = llog_info_init();
573         if (err)
574                 return err;
575
576         err = lustre_register_fs();
577
578         return err;
579 }
580
581 void obd_update_maxusage(void)
582 {
583         __u64 max1, max2;
584
585         max1 = obd_pages_sum();
586         max2 = obd_memory_sum();
587
588         spin_lock(&obd_updatemax_lock);
589         if (max1 > obd_max_pages)
590                 obd_max_pages = max1;
591         if (max2 > obd_max_alloc)
592                 obd_max_alloc = max2;
593         spin_unlock(&obd_updatemax_lock);
594 }
595 EXPORT_SYMBOL(obd_update_maxusage);
596
597 #if defined (CONFIG_PROC_FS)
598 __u64 obd_memory_max(void)
599 {
600         __u64 ret;
601
602         spin_lock(&obd_updatemax_lock);
603         ret = obd_max_alloc;
604         spin_unlock(&obd_updatemax_lock);
605
606         return ret;
607 }
608 EXPORT_SYMBOL(obd_memory_max);
609
610 __u64 obd_pages_max(void)
611 {
612         __u64 ret;
613
614         spin_lock(&obd_updatemax_lock);
615         ret = obd_max_pages;
616         spin_unlock(&obd_updatemax_lock);
617
618         return ret;
619 }
620 EXPORT_SYMBOL(obd_pages_max);
621 #endif
622
623 /* liblustre doesn't call cleanup_obdclass, apparently.  we carry on in this
624  * ifdef to the end of the file to cover module and versioning goo.*/
625 static void cleanup_obdclass(void)
626 {
627         int i;
628         int lustre_unregister_fs(void);
629         __u64 memory_leaked, pages_leaked;
630         __u64 memory_max, pages_max;
631
632         lustre_unregister_fs();
633
634         misc_deregister(&obd_psdev);
635         for (i = 0; i < class_devno_max(); i++) {
636                 struct obd_device *obd = class_num2obd(i);
637                 if (obd && obd->obd_set_up &&
638                     OBT(obd) && OBP(obd, detach)) {
639                         /* XXX should this call generic detach otherwise? */
640                         LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
641                         OBP(obd, detach)(obd);
642                 }
643         }
644         llog_info_fini();
645         cl_global_fini();
646         lu_global_fini();
647
648         obd_cleanup_caches();
649         obd_sysctl_clean();
650
651         class_procfs_clean();
652
653         class_handle_cleanup();
654         class_exit_uuidlist();
655         obd_zombie_impexp_stop();
656
657         memory_leaked = obd_memory_sum();
658         pages_leaked = obd_pages_sum();
659
660         memory_max = obd_memory_max();
661         pages_max = obd_pages_max();
662
663         lprocfs_free_stats(&obd_memory);
664         CDEBUG((memory_leaked) ? D_ERROR : D_INFO,
665                "obd_memory max: %llu, leaked: %llu\n",
666                memory_max, memory_leaked);
667         CDEBUG((pages_leaked) ? D_ERROR : D_INFO,
668                "obd_memory_pages max: %llu, leaked: %llu\n",
669                pages_max, pages_leaked);
670 }
671
672 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
673 MODULE_DESCRIPTION("Lustre Class Driver Build Version: " BUILD_VERSION);
674 MODULE_LICENSE("GPL");
675 MODULE_VERSION(LUSTRE_VERSION_STRING);
676
677 module_init(init_obdclass);
678 module_exit(cleanup_obdclass);