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