OSDN Git Service

7265ecbc6f9d3ea5d88c18aa39e5416f2db36628
[android-x86/kernel.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                 rc = -EINVAL;
181                 goto out;
182         }
183         if (name[len - 1] != 0) {
184                 CERROR("Name not nul terminated!\n");
185                 rc = -EINVAL;
186                 goto out;
187         }
188
189         CDEBUG(D_IOCTL, "device name %s\n", name);
190         dev = class_name2dev(name);
191         if (dev == -1) {
192                 CDEBUG(D_IOCTL, "No device for name %s!\n", name);
193                 rc = -EINVAL;
194                 goto out;
195         }
196
197         CDEBUG(D_IOCTL, "device name %s, dev %d\n", name, dev);
198         rc = dev;
199
200 out:
201         return rc;
202 }
203
204 int class_handle_ioctl(unsigned int cmd, unsigned long arg)
205 {
206         char *buf = NULL;
207         struct obd_ioctl_data *data;
208         struct libcfs_debug_ioctl_data *debug_data;
209         struct obd_device *obd = NULL;
210         int err = 0, len = 0;
211
212         /* only for debugging */
213         if (cmd == LIBCFS_IOC_DEBUG_MASK) {
214                 debug_data = (struct libcfs_debug_ioctl_data *)arg;
215                 libcfs_subsystem_debug = debug_data->subs;
216                 libcfs_debug = debug_data->debug;
217                 return 0;
218         }
219
220         CDEBUG(D_IOCTL, "cmd = %x\n", cmd);
221         if (obd_ioctl_getdata(&buf, &len, (void *)arg)) {
222                 CERROR("OBD ioctl: data error\n");
223                 return -EINVAL;
224         }
225         data = (struct obd_ioctl_data *)buf;
226
227         switch (cmd) {
228         case OBD_IOC_PROCESS_CFG: {
229                 struct lustre_cfg *lcfg;
230
231                 if (!data->ioc_plen1 || !data->ioc_pbuf1) {
232                         CERROR("No config buffer passed!\n");
233                         err = -EINVAL;
234                         goto out;
235                 }
236                 OBD_ALLOC(lcfg, data->ioc_plen1);
237                 if (lcfg == NULL) {
238                         err = -ENOMEM;
239                         goto out;
240                 }
241                 err = copy_from_user(lcfg, data->ioc_pbuf1,
242                                          data->ioc_plen1);
243                 if (!err)
244                         err = lustre_cfg_sanity_check(lcfg, data->ioc_plen1);
245                 if (!err)
246                         err = class_process_config(lcfg);
247
248                 OBD_FREE(lcfg, data->ioc_plen1);
249                 goto out;
250         }
251
252         case OBD_GET_VERSION:
253                 if (!data->ioc_inlbuf1) {
254                         CERROR("No buffer passed in ioctl\n");
255                         err = -EINVAL;
256                         goto out;
257                 }
258
259                 if (strlen(BUILD_VERSION) + 1 > data->ioc_inllen1) {
260                         CERROR("ioctl buffer too small to hold version\n");
261                         err = -EINVAL;
262                         goto out;
263                 }
264
265                 memcpy(data->ioc_bulk, BUILD_VERSION,
266                        strlen(BUILD_VERSION) + 1);
267
268                 err = obd_ioctl_popdata((void *)arg, data, len);
269                 if (err)
270                         err = -EFAULT;
271                 goto out;
272
273         case OBD_IOC_NAME2DEV: {
274                 /* Resolve a device name.  This does not change the
275                  * currently selected device.
276                  */
277                 int dev;
278
279                 dev = class_resolve_dev_name(data->ioc_inllen1,
280                                              data->ioc_inlbuf1);
281                 data->ioc_dev = dev;
282                 if (dev < 0) {
283                         err = -EINVAL;
284                         goto out;
285                 }
286
287                 err = obd_ioctl_popdata((void *)arg, data, sizeof(*data));
288                 if (err)
289                         err = -EFAULT;
290                 goto out;
291         }
292
293         case OBD_IOC_UUID2DEV: {
294                 /* Resolve a device uuid.  This does not change the
295                  * currently selected device.
296                  */
297                 int dev;
298                 struct obd_uuid uuid;
299
300                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
301                         CERROR("No UUID passed!\n");
302                         err = -EINVAL;
303                         goto out;
304                 }
305                 if (data->ioc_inlbuf1[data->ioc_inllen1 - 1] != 0) {
306                         CERROR("UUID not NUL terminated!\n");
307                         err = -EINVAL;
308                         goto out;
309                 }
310
311                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
312                 obd_str2uuid(&uuid, data->ioc_inlbuf1);
313                 dev = class_uuid2dev(&uuid);
314                 data->ioc_dev = dev;
315                 if (dev == -1) {
316                         CDEBUG(D_IOCTL, "No device for UUID %s!\n",
317                                data->ioc_inlbuf1);
318                         err = -EINVAL;
319                         goto out;
320                 }
321
322                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
323                        dev);
324                 err = obd_ioctl_popdata((void *)arg, data, sizeof(*data));
325                 if (err)
326                         err = -EFAULT;
327                 goto out;
328         }
329
330         case OBD_IOC_CLOSE_UUID: {
331                 CDEBUG(D_IOCTL, "closing all connections to uuid %s (NOOP)\n",
332                        data->ioc_inlbuf1);
333                 err = 0;
334                 goto out;
335         }
336
337         case OBD_IOC_GETDEVICE: {
338                 int     index = data->ioc_count;
339                 char    *status, *str;
340
341                 if (!data->ioc_inlbuf1) {
342                         CERROR("No buffer passed in ioctl\n");
343                         err = -EINVAL;
344                         goto out;
345                 }
346                 if (data->ioc_inllen1 < 128) {
347                         CERROR("ioctl buffer too small to hold version\n");
348                         err = -EINVAL;
349                         goto out;
350                 }
351
352                 obd = class_num2obd(index);
353                 if (!obd) {
354                         err = -ENOENT;
355                         goto out;
356                 }
357
358                 if (obd->obd_stopping)
359                         status = "ST";
360                 else if (obd->obd_set_up)
361                         status = "UP";
362                 else if (obd->obd_attached)
363                         status = "AT";
364                 else
365                         status = "--";
366                 str = (char *)data->ioc_bulk;
367                 snprintf(str, len - sizeof(*data), "%3d %s %s %s %s %d",
368                          (int)index, status, obd->obd_type->typ_name,
369                          obd->obd_name, obd->obd_uuid.uuid,
370                          atomic_read(&obd->obd_refcount));
371                 err = obd_ioctl_popdata((void *)arg, data, len);
372
373                 err = 0;
374                 goto out;
375         }
376
377         }
378
379         if (data->ioc_dev == OBD_DEV_BY_DEVNAME) {
380                 if (data->ioc_inllen4 <= 0 || data->ioc_inlbuf4 == NULL) {
381                         err = -EINVAL;
382                         goto out;
383                 }
384                 if (strnlen(data->ioc_inlbuf4, MAX_OBD_NAME) >= MAX_OBD_NAME) {
385                         err = -EINVAL;
386                         goto out;
387                 }
388                 obd = class_name2obd(data->ioc_inlbuf4);
389         } else if (data->ioc_dev < class_devno_max()) {
390                 obd = class_num2obd(data->ioc_dev);
391         } else {
392                 CERROR("OBD ioctl: No device\n");
393                 err = -EINVAL;
394                 goto out;
395         }
396
397         if (obd == NULL) {
398                 CERROR("OBD ioctl : No Device %d\n", data->ioc_dev);
399                 err = -EINVAL;
400                 goto out;
401         }
402         LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
403
404         if (!obd->obd_set_up || obd->obd_stopping) {
405                 CERROR("OBD ioctl: device not setup %d\n", data->ioc_dev);
406                 err = -EINVAL;
407                 goto out;
408         }
409
410         switch (cmd) {
411         case OBD_IOC_NO_TRANSNO: {
412                 if (!obd->obd_attached) {
413                         CERROR("Device %d not attached\n", obd->obd_minor);
414                         err = -ENODEV;
415                         goto out;
416                 }
417                 CDEBUG(D_HA, "%s: disabling committed-transno notification\n",
418                        obd->obd_name);
419                 obd->obd_no_transno = 1;
420                 err = 0;
421                 goto out;
422         }
423
424         default: {
425                 err = obd_iocontrol(cmd, obd->obd_self_export, len, data, NULL);
426                 if (err)
427                         goto out;
428
429                 err = obd_ioctl_popdata((void *)arg, data, len);
430                 if (err)
431                         err = -EFAULT;
432                 goto out;
433         }
434         }
435
436  out:
437         if (buf)
438                 obd_ioctl_freedata(buf, len);
439         return err;
440 } /* class_handle_ioctl */
441
442 extern struct miscdevice obd_psdev;
443
444 #define OBD_INIT_CHECK
445 int obd_init_checks(void)
446 {
447         __u64 u64val, div64val;
448         char buf[64];
449         int len, ret = 0;
450
451         CDEBUG(D_INFO, "LPU64=%s, LPD64=%s, LPX64=%s\n", "%llu", "%lld", "%#llx");
452
453         CDEBUG(D_INFO, "OBD_OBJECT_EOF = %#llx\n", (__u64)OBD_OBJECT_EOF);
454
455         u64val = OBD_OBJECT_EOF;
456         CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
457         if (u64val != OBD_OBJECT_EOF) {
458                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
459                        u64val, (int)sizeof(u64val));
460                 ret = -EINVAL;
461         }
462         len = snprintf(buf, sizeof(buf), "%#llx", u64val);
463         if (len != 18) {
464                 CWARN("LPX64 wrong length! strlen(%s)=%d != 18\n", buf, len);
465                 ret = -EINVAL;
466         }
467
468         div64val = OBD_OBJECT_EOF;
469         CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
470         if (u64val != OBD_OBJECT_EOF) {
471                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
472                        u64val, (int)sizeof(u64val));
473                 ret = -EOVERFLOW;
474         }
475         if (u64val >> 8 != OBD_OBJECT_EOF >> 8) {
476                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
477                        u64val, (int)sizeof(u64val));
478                 return -EOVERFLOW;
479         }
480         if (do_div(div64val, 256) != (u64val & 255)) {
481                 CERROR("do_div(%#llx,256) != %llu\n", u64val, u64val &255);
482                 return -EOVERFLOW;
483         }
484         if (u64val >> 8 != div64val) {
485                 CERROR("do_div(%#llx,256) %llu != %llu\n",
486                        u64val, div64val, u64val >> 8);
487                 return -EOVERFLOW;
488         }
489         len = snprintf(buf, sizeof(buf), "%#llx", u64val);
490         if (len != 18) {
491                 CWARN("LPX64 wrong length! strlen(%s)=%d != 18\n", buf, len);
492                 ret = -EINVAL;
493         }
494         len = snprintf(buf, sizeof(buf), "%llu", u64val);
495         if (len != 20) {
496                 CWARN("LPU64 wrong length! strlen(%s)=%d != 20\n", buf, len);
497                 ret = -EINVAL;
498         }
499         len = snprintf(buf, sizeof(buf), "%lld", u64val);
500         if (len != 2) {
501                 CWARN("LPD64 wrong length! strlen(%s)=%d != 2\n", buf, len);
502                 ret = -EINVAL;
503         }
504         if ((u64val & ~CFS_PAGE_MASK) >= PAGE_CACHE_SIZE) {
505                 CWARN("mask failed: u64val %llu >= %llu\n", u64val,
506                       (__u64)PAGE_CACHE_SIZE);
507                 ret = -EINVAL;
508         }
509
510         return ret;
511 }
512
513 extern spinlock_t obd_types_lock;
514 #if defined (CONFIG_PROC_FS)
515 extern int class_procfs_init(void);
516 extern int class_procfs_clean(void);
517 #else
518 static inline int class_procfs_init(void)
519 { return 0; }
520 static inline int class_procfs_clean(void)
521 { return 0; }
522 #endif
523
524 static int __init init_obdclass(void)
525 {
526         int i, err;
527         int lustre_register_fs(void);
528
529         for (i = CAPA_SITE_CLIENT; i < CAPA_SITE_MAX; i++)
530                 INIT_LIST_HEAD(&capa_list[i]);
531
532         LCONSOLE_INFO("Lustre: Build Version: "BUILD_VERSION"\n");
533
534         spin_lock_init(&obd_types_lock);
535         obd_zombie_impexp_init();
536
537         if (IS_ENABLED(CONFIG_PROC_FS)) {
538                 obd_memory = lprocfs_alloc_stats(OBD_STATS_NUM,
539                                                  LPROCFS_STATS_FLAG_NONE |
540                                                  LPROCFS_STATS_FLAG_IRQ_SAFE);
541
542                 if (obd_memory == NULL) {
543                         CERROR("kmalloc of 'obd_memory' failed\n");
544                         return -ENOMEM;
545                 }
546
547                 lprocfs_counter_init(obd_memory, OBD_MEMORY_STAT,
548                                      LPROCFS_CNTR_AVGMINMAX,
549                                      "memused", "bytes");
550                 lprocfs_counter_init(obd_memory, OBD_MEMORY_PAGES_STAT,
551                                      LPROCFS_CNTR_AVGMINMAX,
552                                      "pagesused", "pages");
553         }
554
555         err = obd_init_checks();
556         if (err == -EOVERFLOW)
557                 return err;
558
559         class_init_uuidlist();
560         err = class_handle_init();
561         if (err)
562                 return err;
563
564         INIT_LIST_HEAD(&obd_types);
565
566         err = misc_register(&obd_psdev);
567         if (err) {
568                 CERROR("cannot register %d err %d\n", OBD_DEV_MINOR, err);
569                 return err;
570         }
571
572         /* This struct is already zeroed for us (static global) */
573         for (i = 0; i < class_devno_max(); i++)
574                 obd_devs[i] = NULL;
575
576         /* Default the dirty page cache cap to 1/2 of system memory.
577          * For clients with less memory, a larger fraction is needed
578          * for other purposes (mostly for BGL). */
579         if (totalram_pages <= 512 << (20 - PAGE_CACHE_SHIFT))
580                 obd_max_dirty_pages = totalram_pages / 4;
581         else
582                 obd_max_dirty_pages = totalram_pages / 2;
583
584         err = obd_init_caches();
585         if (err)
586                 return err;
587
588         obd_sysctl_init();
589
590         err = class_procfs_init();
591         if (err)
592                 return err;
593
594         err = lu_global_init();
595         if (err)
596                 return err;
597
598         err = cl_global_init();
599         if (err != 0)
600                 return err;
601
602
603         err = llog_info_init();
604         if (err)
605                 return err;
606
607         err = lustre_register_fs();
608
609         return err;
610 }
611
612 void obd_update_maxusage(void)
613 {
614         __u64 max1, max2;
615
616         max1 = obd_pages_sum();
617         max2 = obd_memory_sum();
618
619         spin_lock(&obd_updatemax_lock);
620         if (max1 > obd_max_pages)
621                 obd_max_pages = max1;
622         if (max2 > obd_max_alloc)
623                 obd_max_alloc = max2;
624         spin_unlock(&obd_updatemax_lock);
625 }
626 EXPORT_SYMBOL(obd_update_maxusage);
627
628 #if defined (CONFIG_PROC_FS)
629 __u64 obd_memory_max(void)
630 {
631         __u64 ret;
632
633         spin_lock(&obd_updatemax_lock);
634         ret = obd_max_alloc;
635         spin_unlock(&obd_updatemax_lock);
636
637         return ret;
638 }
639 EXPORT_SYMBOL(obd_memory_max);
640
641 __u64 obd_pages_max(void)
642 {
643         __u64 ret;
644
645         spin_lock(&obd_updatemax_lock);
646         ret = obd_max_pages;
647         spin_unlock(&obd_updatemax_lock);
648
649         return ret;
650 }
651 EXPORT_SYMBOL(obd_pages_max);
652 #endif
653
654 /* liblustre doesn't call cleanup_obdclass, apparently.  we carry on in this
655  * ifdef to the end of the file to cover module and versioning goo.*/
656 static void cleanup_obdclass(void)
657 {
658         int i;
659         int lustre_unregister_fs(void);
660         __u64 memory_leaked, pages_leaked;
661         __u64 memory_max, pages_max;
662
663         lustre_unregister_fs();
664
665         misc_deregister(&obd_psdev);
666         for (i = 0; i < class_devno_max(); i++) {
667                 struct obd_device *obd = class_num2obd(i);
668                 if (obd && obd->obd_set_up &&
669                     OBT(obd) && OBP(obd, detach)) {
670                         /* XXX should this call generic detach otherwise? */
671                         LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
672                         OBP(obd, detach)(obd);
673                 }
674         }
675         llog_info_fini();
676         cl_global_fini();
677         lu_global_fini();
678
679         obd_cleanup_caches();
680         obd_sysctl_clean();
681
682         class_procfs_clean();
683
684         class_handle_cleanup();
685         class_exit_uuidlist();
686         obd_zombie_impexp_stop();
687
688         memory_leaked = obd_memory_sum();
689         pages_leaked = obd_pages_sum();
690
691         memory_max = obd_memory_max();
692         pages_max = obd_pages_max();
693
694         lprocfs_free_stats(&obd_memory);
695         CDEBUG((memory_leaked) ? D_ERROR : D_INFO,
696                "obd_memory max: %llu, leaked: %llu\n",
697                memory_max, memory_leaked);
698         CDEBUG((pages_leaked) ? D_ERROR : D_INFO,
699                "obd_memory_pages max: %llu, leaked: %llu\n",
700                pages_max, pages_leaked);
701 }
702
703 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
704 MODULE_DESCRIPTION("Lustre Class Driver Build Version: " BUILD_VERSION);
705 MODULE_LICENSE("GPL");
706 MODULE_VERSION(LUSTRE_VERSION_STRING);
707
708 module_init(init_obdclass);
709 module_exit(cleanup_obdclass);