Whamcloud - gitweb
a47d43496239df981694e66756466fd8f5567ee4
[fs/lustre-release.git] / 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.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2011, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  */
32
33 #define DEBUG_SUBSYSTEM S_CLASS
34
35 #include <linux/miscdevice.h>
36 #include <linux/user_namespace.h>
37 #include <linux/uidgid.h>
38 #include <linux/atomic.h>
39 #include <linux/list.h>
40
41 #include <obd_support.h>
42 #include <obd_class.h>
43 #include <uapi/linux/lnet/lnetctl.h>
44 #include <lustre_kernelcomm.h>
45 #include <lprocfs_status.h>
46 #include <cl_object.h>
47 #ifdef HAVE_SERVER_SUPPORT
48 # include <dt_object.h>
49 # include <md_object.h>
50 #endif /* HAVE_SERVER_SUPPORT */
51 #include <uapi/linux/lustre/lustre_ioctl.h>
52 #include "llog_internal.h"
53
54 #ifdef CONFIG_PROC_FS
55 static __u64 obd_max_alloc;
56 #else
57 __u64 obd_max_alloc;
58 #endif
59
60 static DEFINE_SPINLOCK(obd_updatemax_lock);
61
62 /* The following are visible and mutable through /proc/sys/lustre/. */
63 unsigned int obd_debug_peer_on_timeout;
64 EXPORT_SYMBOL(obd_debug_peer_on_timeout);
65 unsigned int obd_dump_on_timeout;
66 EXPORT_SYMBOL(obd_dump_on_timeout);
67 unsigned int obd_dump_on_eviction;
68 EXPORT_SYMBOL(obd_dump_on_eviction);
69 unsigned int obd_lbug_on_eviction;
70 EXPORT_SYMBOL(obd_lbug_on_eviction);
71 unsigned long obd_max_dirty_pages;
72 EXPORT_SYMBOL(obd_max_dirty_pages);
73 atomic_long_t obd_dirty_pages;
74 EXPORT_SYMBOL(obd_dirty_pages);
75 unsigned int obd_timeout = OBD_TIMEOUT_DEFAULT;   /* seconds */
76 EXPORT_SYMBOL(obd_timeout);
77 unsigned int ldlm_timeout = LDLM_TIMEOUT_DEFAULT; /* seconds */
78 EXPORT_SYMBOL(ldlm_timeout);
79 unsigned int obd_timeout_set;
80 EXPORT_SYMBOL(obd_timeout_set);
81 unsigned int ldlm_timeout_set;
82 EXPORT_SYMBOL(ldlm_timeout_set);
83 /* bulk transfer timeout, give up after 100s by default */
84 unsigned int bulk_timeout = 100; /* seconds */
85 EXPORT_SYMBOL(bulk_timeout);
86 /* Adaptive timeout defs here instead of ptlrpc module for /proc/sys/ access */
87 unsigned int at_min = 0;
88 EXPORT_SYMBOL(at_min);
89 unsigned int at_max = 600;
90 EXPORT_SYMBOL(at_max);
91 unsigned int at_history = 600;
92 EXPORT_SYMBOL(at_history);
93 int at_early_margin = 5;
94 EXPORT_SYMBOL(at_early_margin);
95 int at_extra = 30;
96 EXPORT_SYMBOL(at_extra);
97
98 #ifdef CONFIG_PROC_FS
99 struct lprocfs_stats *obd_memory = NULL;
100 EXPORT_SYMBOL(obd_memory);
101 #endif
102
103 static int class_resolve_dev_name(__u32 len, const char *name)
104 {
105         int rc;
106         int dev;
107
108         ENTRY;
109         if (!len || !name) {
110                 CERROR("No name passed,!\n");
111                 GOTO(out, rc = -EINVAL);
112         }
113         if (name[len - 1] != 0) {
114                 CERROR("Name not nul terminated!\n");
115                 GOTO(out, rc = -EINVAL);
116         }
117
118         CDEBUG(D_IOCTL, "device name %s\n", name);
119         dev = class_name2dev(name);
120         if (dev == -1) {
121                 CDEBUG(D_IOCTL, "No device for name %s!\n", name);
122                 GOTO(out, rc = -EINVAL);
123         }
124
125         CDEBUG(D_IOCTL, "device name %s, dev %d\n", name, dev);
126         rc = dev;
127
128 out:
129         RETURN(rc);
130 }
131
132 #define OBD_MAX_IOCTL_BUFFER    8192
133
134 static int obd_ioctl_is_invalid(struct obd_ioctl_data *data)
135 {
136         const int maxlen = 1 << 30;
137         if (data->ioc_len > maxlen) {
138                 CERROR("OBD ioctl: ioc_len larger than 1<<30\n");
139                 return 1;
140         }
141
142         if (data->ioc_inllen1 > maxlen) {
143                 CERROR("OBD ioctl: ioc_inllen1 larger than 1<<30\n");
144                 return 1;
145         }
146
147         if (data->ioc_inllen2 > maxlen) {
148                 CERROR("OBD ioctl: ioc_inllen2 larger than 1<<30\n");
149                 return 1;
150         }
151
152         if (data->ioc_inllen3 > maxlen) {
153                 CERROR("OBD ioctl: ioc_inllen3 larger than 1<<30\n");
154                 return 1;
155         }
156
157         if (data->ioc_inllen4 > maxlen) {
158                 CERROR("OBD ioctl: ioc_inllen4 larger than 1<<30\n");
159                 return 1;
160         }
161
162         if (data->ioc_inlbuf1 && data->ioc_inllen1 == 0) {
163                 CERROR("OBD ioctl: inlbuf1 pointer but 0 length\n");
164                 return 1;
165         }
166
167         if (data->ioc_inlbuf2 && data->ioc_inllen2 == 0) {
168                 CERROR("OBD ioctl: inlbuf2 pointer but 0 length\n");
169                 return 1;
170         }
171
172         if (data->ioc_inlbuf3 && data->ioc_inllen3 == 0) {
173                 CERROR("OBD ioctl: inlbuf3 pointer but 0 length\n");
174                 return 1;
175         }
176
177         if (data->ioc_inlbuf4 && data->ioc_inllen4 == 0) {
178                 CERROR("OBD ioctl: inlbuf4 pointer but 0 length\n");
179                 return 1;
180         }
181
182         if (data->ioc_pbuf1 && data->ioc_plen1 == 0) {
183                 CERROR("OBD ioctl: pbuf1 pointer but 0 length\n");
184                 return 1;
185         }
186
187         if (data->ioc_pbuf2 && data->ioc_plen2 == 0) {
188                 CERROR("OBD ioctl: pbuf2 pointer but 0 length\n");
189                 return 1;
190         }
191
192         if (!data->ioc_pbuf1 && data->ioc_plen1 != 0) {
193                 CERROR("OBD ioctl: plen1 set but NULL pointer\n");
194                 return 1;
195         }
196
197         if (!data->ioc_pbuf2 && data->ioc_plen2 != 0) {
198                 CERROR("OBD ioctl: plen2 set but NULL pointer\n");
199                 return 1;
200         }
201
202         if (obd_ioctl_packlen(data) > data->ioc_len) {
203                 CERROR("OBD ioctl: packlen exceeds ioc_len (%d > %d)\n",
204                        obd_ioctl_packlen(data), data->ioc_len);
205                 return 1;
206         }
207
208         return 0;
209 }
210
211 /* buffer MUST be at least the size of obd_ioctl_hdr */
212 int obd_ioctl_getdata(struct obd_ioctl_data **datap, int *len, void __user *arg)
213 {
214         struct obd_ioctl_hdr hdr;
215         struct obd_ioctl_data *data;
216         int offset = 0;
217
218         ENTRY;
219         if (copy_from_user(&hdr, arg, sizeof(hdr)))
220                 RETURN(-EFAULT);
221
222         if (hdr.ioc_version != OBD_IOCTL_VERSION) {
223                 CERROR("Version mismatch kernel (%x) vs application (%x)\n",
224                        OBD_IOCTL_VERSION, hdr.ioc_version);
225                 RETURN(-EINVAL);
226         }
227
228         if (hdr.ioc_len > OBD_MAX_IOCTL_BUFFER) {
229                 CERROR("User buffer len %d exceeds %d max buffer\n",
230                        hdr.ioc_len, OBD_MAX_IOCTL_BUFFER);
231                 RETURN(-EINVAL);
232         }
233
234         if (hdr.ioc_len < sizeof(struct obd_ioctl_data)) {
235                 CERROR("User buffer too small for ioctl (%d)\n", hdr.ioc_len);
236                 RETURN(-EINVAL);
237         }
238
239         /* When there are lots of processes calling vmalloc on multi-core
240          * system, the high lock contention will hurt performance badly,
241          * obdfilter-survey is an example, which relies on ioctl. So we'd
242          * better avoid vmalloc on ioctl path. LU-66
243          */
244         OBD_ALLOC_LARGE(data, hdr.ioc_len);
245         if (!data) {
246                 CERROR("Cannot allocate control buffer of len %d\n",
247                        hdr.ioc_len);
248                 RETURN(-EINVAL);
249         }
250         *len = hdr.ioc_len;
251
252         if (copy_from_user(data, arg, hdr.ioc_len)) {
253                 OBD_FREE_LARGE(data, hdr.ioc_len);
254                 RETURN(-EFAULT);
255         }
256
257         if (obd_ioctl_is_invalid(data)) {
258                 CERROR("ioctl not correctly formatted\n");
259                 OBD_FREE_LARGE(data, hdr.ioc_len);
260                 RETURN(-EINVAL);
261         }
262
263         if (data->ioc_inllen1) {
264                 data->ioc_inlbuf1 = &data->ioc_bulk[0];
265                 offset += cfs_size_round(data->ioc_inllen1);
266         }
267
268         if (data->ioc_inllen2) {
269                 data->ioc_inlbuf2 = &data->ioc_bulk[0] + offset;
270                 offset += cfs_size_round(data->ioc_inllen2);
271         }
272
273         if (data->ioc_inllen3) {
274                 data->ioc_inlbuf3 = &data->ioc_bulk[0] + offset;
275                 offset += cfs_size_round(data->ioc_inllen3);
276         }
277
278         if (data->ioc_inllen4)
279                 data->ioc_inlbuf4 = &data->ioc_bulk[0] + offset;
280
281         *datap = data;
282
283         RETURN(0);
284 }
285 EXPORT_SYMBOL(obd_ioctl_getdata);
286
287 int class_handle_ioctl(unsigned int cmd, unsigned long arg)
288 {
289         struct obd_ioctl_data *data;
290         struct obd_device *obd = NULL;
291         int err = 0, len = 0;
292
293         ENTRY;
294         CDEBUG(D_IOCTL, "cmd = %x\n", cmd);
295         if (obd_ioctl_getdata(&data, &len, (void __user *)arg)) {
296                 CERROR("OBD ioctl: data error\n");
297                 RETURN(-EINVAL);
298         }
299
300         switch (cmd) {
301         case OBD_IOC_PROCESS_CFG: {
302                 struct lustre_cfg *lcfg;
303
304                 if (!data->ioc_plen1 || !data->ioc_pbuf1) {
305                         CERROR("No config buffer passed!\n");
306                         GOTO(out, err = -EINVAL);
307                 }
308                 OBD_ALLOC(lcfg, data->ioc_plen1);
309                 if (lcfg == NULL)
310                         GOTO(out, err = -ENOMEM);
311                 err = copy_from_user(lcfg, data->ioc_pbuf1,
312                                          data->ioc_plen1);
313                 if (!err)
314                         err = lustre_cfg_sanity_check(lcfg, data->ioc_plen1);
315                 if (!err)
316                         err = class_process_config(lcfg);
317
318                 OBD_FREE(lcfg, data->ioc_plen1);
319                 GOTO(out, err);
320         }
321
322 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
323         case OBD_GET_VERSION: {
324                 static bool warned;
325
326                 if (!data->ioc_inlbuf1) {
327                         CERROR("No buffer passed in ioctl\n");
328                         GOTO(out, err = -EINVAL);
329                 }
330
331                 if (strlen(LUSTRE_VERSION_STRING) + 1 > data->ioc_inllen1) {
332                         CERROR("ioctl buffer too small to hold version\n");
333                         GOTO(out, err = -EINVAL);
334                 }
335
336                 if (!warned) {
337                         warned = true;
338                         CWARN("%s: ioctl(OBD_GET_VERSION) is deprecated, "
339                               "use llapi_get_version_string() and/or relink\n",
340                               current->comm);
341                 }
342                 memcpy(data->ioc_bulk, LUSTRE_VERSION_STRING,
343                        strlen(LUSTRE_VERSION_STRING) + 1);
344
345                 if (copy_to_user((void __user *)arg, data, len))
346                         err = -EFAULT;
347                 GOTO(out, err);
348         }
349 #endif
350         case OBD_IOC_NAME2DEV: {
351                 /* Resolve a device name.  This does not change the
352                  * currently selected device.
353                  */
354                 int dev;
355
356                 dev = class_resolve_dev_name(data->ioc_inllen1,
357                                              data->ioc_inlbuf1);
358                 data->ioc_dev = dev;
359                 if (dev < 0)
360                         GOTO(out, err = -EINVAL);
361
362                 if (copy_to_user((void __user *)arg, data, sizeof(*data)))
363                         err = -EFAULT;
364                 GOTO(out, err);
365         }
366
367         case OBD_IOC_UUID2DEV: {
368                 /* Resolve a device uuid.  This does not change the
369                  * currently selected device.
370                  */
371                 int dev;
372                 struct obd_uuid uuid;
373
374                 if (!data->ioc_inllen1 || !data->ioc_inlbuf1) {
375                         CERROR("No UUID passed!\n");
376                         GOTO(out, err = -EINVAL);
377                 }
378                 if (data->ioc_inlbuf1[data->ioc_inllen1 - 1] != 0) {
379                         CERROR("UUID not NUL terminated!\n");
380                         GOTO(out, err = -EINVAL);
381                 }
382
383                 CDEBUG(D_IOCTL, "device name %s\n", data->ioc_inlbuf1);
384                 obd_str2uuid(&uuid, data->ioc_inlbuf1);
385                 dev = class_uuid2dev(&uuid);
386                 data->ioc_dev = dev;
387                 if (dev == -1) {
388                         CDEBUG(D_IOCTL, "No device for UUID %s!\n",
389                                data->ioc_inlbuf1);
390                         GOTO(out, err = -EINVAL);
391                 }
392
393                 CDEBUG(D_IOCTL, "device name %s, dev %d\n", data->ioc_inlbuf1,
394                        dev);
395                 if (copy_to_user((void __user *)arg, data, sizeof(*data)))
396                         err = -EFAULT;
397                 GOTO(out, err);
398         }
399
400         case OBD_IOC_GETDEVICE: {
401                 int     index = data->ioc_count;
402                 char    *status, *str;
403
404                 if (!data->ioc_inlbuf1) {
405                         CERROR("No buffer passed in ioctl\n");
406                         GOTO(out, err = -EINVAL);
407                 }
408                 if (data->ioc_inllen1 < 128) {
409                         CERROR("ioctl buffer too small to hold version\n");
410                         GOTO(out, err = -EINVAL);
411                 }
412
413                 obd = class_num2obd(index);
414                 if (!obd)
415                         GOTO(out, err = -ENOENT);
416
417                 if (obd->obd_stopping)
418                         status = "ST";
419                 else if (obd->obd_inactive)
420                         status = "IN";
421                 else if (obd->obd_set_up)
422                         status = "UP";
423                 else if (obd->obd_attached)
424                         status = "AT";
425                 else
426                         status = "--";
427
428                 str = (char *)data->ioc_bulk;
429                 snprintf(str, len - sizeof(*data), "%3d %s %s %s %s %d",
430                          (int)index, status, obd->obd_type->typ_name,
431                          obd->obd_name, obd->obd_uuid.uuid,
432                          atomic_read(&obd->obd_refcount));
433
434                 if (copy_to_user((void __user *)arg, data, len))
435                         err = -EFAULT;
436
437                 GOTO(out, err);
438         }
439
440         }
441
442         if (data->ioc_dev == OBD_DEV_BY_DEVNAME) {
443                 if (data->ioc_inllen4 <= 0 || data->ioc_inlbuf4 == NULL)
444                         GOTO(out, err = -EINVAL);
445                 if (strnlen(data->ioc_inlbuf4, MAX_OBD_NAME) >= MAX_OBD_NAME)
446                         GOTO(out, err = -EINVAL);
447                 obd = class_name2obd(data->ioc_inlbuf4);
448         } else if (data->ioc_dev < class_devno_max()) {
449                 obd = class_num2obd(data->ioc_dev);
450         } else {
451                 CERROR("OBD ioctl: No device\n");
452                 GOTO(out, err = -EINVAL);
453         }
454
455         if (obd == NULL) {
456                 CERROR("OBD ioctl : No Device %d\n", data->ioc_dev);
457                 GOTO(out, err = -EINVAL);
458         }
459         LASSERT(obd->obd_magic == OBD_DEVICE_MAGIC);
460
461         if (!obd->obd_set_up || obd->obd_stopping) {
462                 CERROR("OBD ioctl: device not setup %d \n", data->ioc_dev);
463                 GOTO(out, err = -EINVAL);
464         }
465
466         err = obd_iocontrol(cmd, obd->obd_self_export, len, data, NULL);
467         if (err)
468                 GOTO(out, err);
469
470         if (copy_to_user((void __user *)arg, data, len))
471                 err = -EFAULT;
472 out:
473         OBD_FREE_LARGE(data, len);
474         RETURN(err);
475 } /* class_handle_ioctl */
476
477 /* to control /dev/obd */
478 static long obd_class_ioctl(struct file *filp, unsigned int cmd,
479                             unsigned long arg)
480 {
481         int err = 0;
482
483         ENTRY;
484         /* Allow non-root access for some limited ioctls */
485         if (!cfs_capable(CAP_SYS_ADMIN))
486                 RETURN(err = -EACCES);
487
488         if ((cmd & 0xffffff00) == ((int)'T') << 8) /* ignore all tty ioctls */
489                 RETURN(err = -ENOTTY);
490
491         err = class_handle_ioctl(cmd, (unsigned long)arg);
492
493         RETURN(err);
494 }
495
496 /* declare character device */
497 static const struct file_operations obd_psdev_fops = {
498         .owner          = THIS_MODULE,
499         .unlocked_ioctl = obd_class_ioctl,      /* unlocked_ioctl */
500 };
501
502 /* modules setup */
503 static struct miscdevice obd_psdev = {
504         .minor  = MISC_DYNAMIC_MINOR,
505         .name   = OBD_DEV_NAME,
506         .fops   = &obd_psdev_fops,
507 };
508
509 #define test_string_to_size_err(value, expect, def_unit, __rc)                 \
510 ({                                                                             \
511         u64 __size;                                                            \
512         int __ret;                                                             \
513                                                                                \
514         BUILD_BUG_ON(sizeof(value) >= 23);                                     \
515         __ret = sysfs_memparse(value, sizeof(value) - 1, &__size, def_unit);   \
516         if (__ret != __rc)                                                     \
517                 CERROR("string_helper: parsing '%s' expect rc %d != got %d\n", \
518                        value, __rc, __ret);                                    \
519         else if (!__ret && (u64)expect != __size)                              \
520                 CERROR("string_helper: parsing '%s' expect %llu != got %llu\n",\
521                        value, (u64)expect, __size);                            \
522         __ret;                                                                 \
523 })
524 #define test_string_to_size_one(value, expect, def_unit)                       \
525         test_string_to_size_err(value, expect, def_unit, 0)
526
527 static int __init obd_init_checks(void)
528 {
529         __u64 u64val, div64val;
530         char buf[64];
531         int len, ret = 0;
532
533         CDEBUG(D_INFO, "OBD_OBJECT_EOF = %#llx\n", (__u64)OBD_OBJECT_EOF);
534
535         u64val = OBD_OBJECT_EOF;
536         CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
537         if (u64val != OBD_OBJECT_EOF) {
538                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
539                        u64val, (int)sizeof(u64val));
540                 ret = -EINVAL;
541         }
542         len = snprintf(buf, sizeof(buf), "%#llx", u64val);
543         if (len != 18) {
544                 CERROR("u64 hex wrong length, strlen(%s)=%d != 18\n", buf, len);
545                 ret = -EINVAL;
546         }
547
548         div64val = OBD_OBJECT_EOF;
549         CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
550         if (u64val != OBD_OBJECT_EOF) {
551                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
552                        u64val, (int)sizeof(u64val));
553                 ret = -EOVERFLOW;
554         }
555         if (u64val >> 8 != OBD_OBJECT_EOF >> 8) {
556                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
557                        u64val, (int)sizeof(u64val));
558                 ret = -EOVERFLOW;
559         }
560         if (do_div(div64val, 256) != (u64val & 255)) {
561                 CERROR("do_div(%#llx,256) != %llu\n", u64val, u64val & 255);
562                 ret = -EOVERFLOW;
563         }
564         if (u64val >> 8 != div64val) {
565                 CERROR("do_div(%#llx,256) %llu != %llu\n",
566                        u64val, div64val, u64val >> 8);
567                 ret = -EOVERFLOW;
568         }
569         len = snprintf(buf, sizeof(buf), "%#llx", u64val);
570         if (len != 18) {
571                 CERROR("u64 hex wrong length! strlen(%s)=%d != 18\n", buf, len);
572                 ret = -EINVAL;
573         }
574         len = snprintf(buf, sizeof(buf), "%llu", u64val);
575         if (len != 20) {
576                 CERROR("u64 wrong length! strlen(%s)=%d != 20\n", buf, len);
577                 ret = -EINVAL;
578         }
579         len = snprintf(buf, sizeof(buf), "%lld", u64val);
580         if (len != 2) {
581                 CERROR("s64 wrong length! strlen(%s)=%d != 2\n", buf, len);
582                 ret = -EINVAL;
583         }
584         if ((u64val & ~PAGE_MASK) >= PAGE_SIZE) {
585                 CERROR("mask failed: u64val %llu >= %llu\n", u64val,
586                        (__u64)PAGE_SIZE);
587                 ret = -EINVAL;
588         }
589         if (ret)
590                 RETURN(ret);
591
592         /* invalid string */
593         if (!test_string_to_size_err("256B34", 256, "B", -EINVAL)) {
594                 CERROR("string_helpers: format should be number then units\n");
595                 ret = -EINVAL;
596         }
597         if (!test_string_to_size_err("132OpQ", 132, "B", -EINVAL)) {
598                 CERROR("string_helpers: invalid units should be rejected\n");
599                 ret = -EINVAL;
600         }
601         if (!test_string_to_size_err("1.82B", 1, "B", -EINVAL)) {
602                 CERROR("string_helpers: 'B' with '.' should be invalid\n");
603                 ret = -EINVAL;
604         }
605         if (test_string_to_size_one("343\n", 343, "B")) {
606                 CERROR("string_helpers: should ignore newline\n");
607                 ret = -EINVAL;
608         }
609         if (ret)
610                 RETURN(ret);
611
612         /* memparse unit handling */
613         ret = 0;
614         ret += test_string_to_size_one("0B", 0, "B");
615         ret += test_string_to_size_one("512B", 512, "B");
616         ret += test_string_to_size_one("1.067kB", 1067, "B");
617         ret += test_string_to_size_one("1.042KiB", 1067, "B");
618         ret += test_string_to_size_one("8", 8388608, "M");
619         ret += test_string_to_size_one("65536", 65536, "B");
620         ret += test_string_to_size_one("128", 131072, "K");
621         ret += test_string_to_size_one("1M", 1048576, "B");
622         ret += test_string_to_size_one("0.5T", 549755813888ULL, "T");
623         ret += test_string_to_size_one("256.5G", 275414777856ULL, "G");
624         if (ret)
625                 RETURN(ret);
626
627         /* string helper values */
628         ret += test_string_to_size_one("16", 16777216, "MiB");
629         ret += test_string_to_size_one("8.39MB", 8390000, "MiB");
630         ret += test_string_to_size_one("8.00MiB", 8388608, "MiB");
631         ret += test_string_to_size_one("256GB", 256000000000ULL, "GiB");
632         ret += test_string_to_size_one("238.731GiB", 256335459385ULL, "GiB");
633         if (ret)
634                 RETURN(ret);
635
636         /* huge values */
637         ret += test_string_to_size_one("0.4TB", 400000000000ULL, "TiB");
638         ret += test_string_to_size_one("12.5TiB", 13743895347200ULL, "TiB");
639         ret += test_string_to_size_one("2PB", 2000000000000000ULL, "PiB");
640         ret += test_string_to_size_one("16PiB", 18014398509481984ULL, "PiB");
641         if (ret)
642                 RETURN(ret);
643
644         /* huge values should overflow */
645         if (!test_string_to_size_err("1000EiB", 0, "EiB", -EOVERFLOW)) {
646                 CERROR("string_helpers: failed to detect binary overflow\n");
647                 ret = -EINVAL;
648         }
649         if (!test_string_to_size_err("1000EB", 0, "EiB", -EOVERFLOW)) {
650                 CERROR("string_helpers: failed to detect decimal overflow\n");
651                 ret = -EINVAL;
652         }
653
654         return ret;
655 }
656
657 static int __init obdclass_init(void)
658 {
659         int err;
660
661         LCONSOLE_INFO("Lustre: Build Version: "LUSTRE_VERSION_STRING"\n");
662
663         libcfs_kkuc_init();
664
665         err = obd_init_checks();
666         if (err)
667                 return err;
668
669 #ifdef CONFIG_PROC_FS
670         obd_memory = lprocfs_alloc_stats(OBD_STATS_NUM,
671                                          LPROCFS_STATS_FLAG_NONE |
672                                          LPROCFS_STATS_FLAG_IRQ_SAFE);
673         if (obd_memory == NULL) {
674                 CERROR("kmalloc of 'obd_memory' failed\n");
675                 return -ENOMEM;
676         }
677
678         lprocfs_counter_init(obd_memory, OBD_MEMORY_STAT,
679                              LPROCFS_CNTR_AVGMINMAX,
680                              "memused", "bytes");
681 #endif
682         err = obd_zombie_impexp_init();
683         if (err)
684                 goto cleanup_obd_memory;
685
686         err = class_handle_init();
687         if (err)
688                 goto cleanup_zombie_impexp;
689
690         err = misc_register(&obd_psdev);
691         if (err) {
692                 CERROR("cannot register OBD miscdevice: err = %d\n", err);
693                 goto cleanup_class_handle;
694         }
695
696         /* Default the dirty page cache cap to 1/2 of system memory.
697          * For clients with less memory, a larger fraction is needed
698          * for other purposes (mostly for BGL). */
699         if (cfs_totalram_pages() <= 512 << (20 - PAGE_SHIFT))
700                 obd_max_dirty_pages = cfs_totalram_pages() / 4;
701         else
702                 obd_max_dirty_pages = cfs_totalram_pages() / 2;
703
704         err = obd_init_caches();
705         if (err)
706                 goto cleanup_deregister;
707
708         err = class_procfs_init();
709         if (err)
710                 goto cleanup_caches;
711
712         err = lu_global_init();
713         if (err)
714                 goto cleanup_class_procfs;
715
716         err = cl_global_init();
717         if (err != 0)
718                 goto cleanup_lu_global;
719
720 #ifdef HAVE_SERVER_SUPPORT
721         err = dt_global_init();
722         if (err != 0)
723                 goto cleanup_cl_global;
724
725         err = lu_ucred_global_init();
726         if (err != 0)
727                 goto cleanup_dt_global;
728 #endif /* HAVE_SERVER_SUPPORT */
729
730         err = llog_info_init();
731         if (err)
732 #ifdef HAVE_SERVER_SUPPORT
733                 goto cleanup_lu_ucred_global;
734 #else /* !HAVE_SERVER_SUPPORT */
735                 goto cleanup_cl_global;
736 #endif /* HAVE_SERVER_SUPPORT */
737
738         err = lustre_register_fs();
739
740         /* simulate a late OOM situation now to require all
741          * alloc'ed/initialized resources to be freed */
742         if (OBD_FAIL_CHECK(OBD_FAIL_OBDCLASS_MODULE_LOAD)) {
743                 /* fake error but filesystem has been registered */
744                 lustre_unregister_fs();
745                 /* force error to ensure module will be unloaded/cleaned */
746                 err = -ENOMEM;
747         }
748
749         if (err)
750                 goto cleanup_llog_info;
751
752         return 0;
753
754 cleanup_llog_info:
755         llog_info_fini();
756
757 #ifdef HAVE_SERVER_SUPPORT
758 cleanup_lu_ucred_global:
759         lu_ucred_global_fini();
760
761 cleanup_dt_global:
762         dt_global_fini();
763 #endif /* HAVE_SERVER_SUPPORT */
764
765 cleanup_cl_global:
766         cl_global_fini();
767
768 cleanup_lu_global:
769         lu_global_fini();
770
771 cleanup_class_procfs:
772         class_procfs_clean();
773
774 cleanup_caches:
775         obd_cleanup_caches();
776
777 cleanup_deregister:
778         misc_deregister(&obd_psdev);
779
780 cleanup_class_handle:
781         class_handle_cleanup();
782
783 cleanup_zombie_impexp:
784         obd_zombie_impexp_stop();
785
786 cleanup_obd_memory:
787 #ifdef CONFIG_PROC_FS
788         lprocfs_free_stats(&obd_memory);
789 #endif
790
791         return err;
792 }
793
794 void obd_update_maxusage(void)
795 {
796         __u64 max;
797
798         max = obd_memory_sum();
799
800         spin_lock(&obd_updatemax_lock);
801         if (max > obd_max_alloc)
802                 obd_max_alloc = max;
803         spin_unlock(&obd_updatemax_lock);
804 }
805 EXPORT_SYMBOL(obd_update_maxusage);
806
807 #ifdef CONFIG_PROC_FS
808 __u64 obd_memory_max(void)
809 {
810         __u64 ret;
811
812         obd_update_maxusage();
813         spin_lock(&obd_updatemax_lock);
814         ret = obd_max_alloc;
815         spin_unlock(&obd_updatemax_lock);
816
817         return ret;
818 }
819 #endif /* CONFIG_PROC_FS */
820
821 static void __exit obdclass_exit(void)
822 {
823 #ifdef CONFIG_PROC_FS
824         __u64 memory_leaked;
825         __u64 memory_max;
826 #endif /* CONFIG_PROC_FS */
827         ENTRY;
828
829         lustre_unregister_fs();
830
831         misc_deregister(&obd_psdev);
832         llog_info_fini();
833 #ifdef HAVE_SERVER_SUPPORT
834         lu_ucred_global_fini();
835         dt_global_fini();
836 #endif /* HAVE_SERVER_SUPPORT */
837         cl_global_fini();
838         lu_global_fini();
839
840         obd_cleanup_caches();
841
842         class_procfs_clean();
843
844         class_handle_cleanup();
845         class_del_uuid(NULL); /* Delete all UUIDs. */
846         obd_zombie_impexp_stop();
847
848 #ifdef CONFIG_PROC_FS
849         memory_leaked = obd_memory_sum();
850         memory_max = obd_memory_max();
851
852         lprocfs_free_stats(&obd_memory);
853         /* the below message is checked in test-framework.sh check_mem_leak() */
854         CDEBUG((memory_leaked) ? D_ERROR : D_INFO,
855                "obd_memory max: %llu, leaked: %llu\n",
856                memory_max, memory_leaked);
857 #endif /* CONFIG_PROC_FS */
858
859         EXIT;
860 }
861
862 void obd_heat_clear(struct obd_heat_instance *instance, int count)
863 {
864         ENTRY;
865
866         memset(instance, 0, sizeof(*instance) * count);
867         RETURN_EXIT;
868 }
869 EXPORT_SYMBOL(obd_heat_clear);
870
871 /*
872  * The file heat is calculated for every time interval period I. The access
873  * frequency during each period is counted. The file heat is only recalculated
874  * at the end of a time period.  And a percentage of the former file heat is
875  * lost when recalculated. The recursion formula to calculate the heat of the
876  * file f is as follow:
877  *
878  * Hi+1(f) = (1-P)*Hi(f)+ P*Ci
879  *
880  * Where Hi is the heat value in the period between time points i*I and
881  * (i+1)*I; Ci is the access count in the period; the symbol P refers to the
882  * weight of Ci. The larger the value the value of P is, the more influence Ci
883  * has on the file heat.
884  */
885 void obd_heat_decay(struct obd_heat_instance *instance,  __u64 time_second,
886                     unsigned int weight, unsigned int period_second)
887 {
888         u64 second;
889
890         ENTRY;
891
892         if (instance->ohi_time_second > time_second) {
893                 obd_heat_clear(instance, 1);
894                 RETURN_EXIT;
895         }
896
897         if (instance->ohi_time_second == 0)
898                 RETURN_EXIT;
899
900         for (second = instance->ohi_time_second + period_second;
901              second < time_second;
902              second += period_second) {
903                 instance->ohi_heat = instance->ohi_heat *
904                                 (256 - weight) / 256 +
905                                 instance->ohi_count * weight / 256;
906                 instance->ohi_count = 0;
907                 instance->ohi_time_second = second;
908         }
909         RETURN_EXIT;
910 }
911 EXPORT_SYMBOL(obd_heat_decay);
912
913 __u64 obd_heat_get(struct obd_heat_instance *instance, unsigned int time_second,
914                    unsigned int weight, unsigned int period_second)
915 {
916         ENTRY;
917
918         obd_heat_decay(instance, time_second, weight, period_second);
919
920         if (instance->ohi_count == 0)
921                 RETURN(instance->ohi_heat);
922
923         RETURN(instance->ohi_heat * (256 - weight) / 256 +
924                instance->ohi_count * weight / 256);
925 }
926 EXPORT_SYMBOL(obd_heat_get);
927
928 void obd_heat_add(struct obd_heat_instance *instance,
929                   unsigned int time_second,  __u64 count,
930                   unsigned int weight, unsigned int period_second)
931 {
932         ENTRY;
933
934         obd_heat_decay(instance, time_second, weight, period_second);
935         if (instance->ohi_time_second == 0) {
936                 instance->ohi_time_second = time_second;
937                 instance->ohi_heat = 0;
938                 instance->ohi_count = count;
939         } else {
940                 instance->ohi_count += count;
941         }
942         RETURN_EXIT;
943 }
944 EXPORT_SYMBOL(obd_heat_add);
945
946 MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
947 MODULE_DESCRIPTION("Lustre Class Driver");
948 MODULE_VERSION(LUSTRE_VERSION_STRING);
949 MODULE_LICENSE("GPL");
950
951 module_init(obdclass_init);
952 module_exit(obdclass_exit);