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