Whamcloud - gitweb
LU-6202 obd: replace OBD_IOC_NO_TRANSNO with sysfs file
[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         err = obd_iocontrol(cmd, obd->obd_self_export, len, data, NULL);
468         if (err)
469                 GOTO(out, err);
470
471         if (copy_to_user((void __user *)arg, data, len))
472                 err = -EFAULT;
473 out:
474         OBD_FREE_LARGE(buf, len);
475         RETURN(err);
476 } /* class_handle_ioctl */
477
478 /* to control /dev/obd */
479 static long obd_class_ioctl(struct file *filp, unsigned int cmd,
480                             unsigned long arg)
481 {
482         int err = 0;
483
484         ENTRY;
485         /* Allow non-root access for some limited ioctls */
486         if (!cfs_capable(CFS_CAP_SYS_ADMIN))
487                 RETURN(err = -EACCES);
488
489         if ((cmd & 0xffffff00) == ((int)'T') << 8) /* ignore all tty ioctls */
490                 RETURN(err = -ENOTTY);
491
492         err = class_handle_ioctl(cmd, (unsigned long)arg);
493
494         RETURN(err);
495 }
496
497 /* declare character device */
498 static struct file_operations obd_psdev_fops = {
499         .owner          = THIS_MODULE,
500         .unlocked_ioctl = obd_class_ioctl,      /* unlocked_ioctl */
501 };
502
503 /* modules setup */
504 struct miscdevice obd_psdev = {
505         .minor  = MISC_DYNAMIC_MINOR,
506         .name   = OBD_DEV_NAME,
507         .fops   = &obd_psdev_fops,
508 };
509
510 #define test_string_to_size_err(value, expect, def_unit, __rc)                 \
511 ({                                                                             \
512         u64 __size;                                                            \
513         int __ret;                                                             \
514                                                                                \
515         BUILD_BUG_ON(sizeof(value) >= 23);                                     \
516         __ret = sysfs_memparse(value, sizeof(value) - 1, &__size, def_unit);   \
517         if (__ret != __rc)                                                     \
518                 CERROR("string_helper: parsing '%s' expect rc %d != got %d\n", \
519                        value, __rc, __ret);                                    \
520         else if (!__ret && (u64)expect != __size)                              \
521                 CERROR("string_helper: parsing '%s' expect %llu != got %llu\n",\
522                        value, (u64)expect, __size);                            \
523         __ret;                                                                 \
524 })
525 #define test_string_to_size_one(value, expect, def_unit)                       \
526         test_string_to_size_err(value, expect, def_unit, 0)
527
528 static int __init obd_init_checks(void)
529 {
530         __u64 u64val, div64val;
531         char buf[64];
532         int len, ret = 0;
533
534         CDEBUG(D_INFO, "OBD_OBJECT_EOF = %#llx\n", (__u64)OBD_OBJECT_EOF);
535
536         u64val = OBD_OBJECT_EOF;
537         CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
538         if (u64val != OBD_OBJECT_EOF) {
539                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
540                        u64val, (int)sizeof(u64val));
541                 ret = -EINVAL;
542         }
543         len = snprintf(buf, sizeof(buf), "%#llx", u64val);
544         if (len != 18) {
545                 CERROR("u64 hex wrong length, strlen(%s)=%d != 18\n", buf, len);
546                 ret = -EINVAL;
547         }
548
549         div64val = 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 = -EOVERFLOW;
555         }
556         if (u64val >> 8 != OBD_OBJECT_EOF >> 8) {
557                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
558                        u64val, (int)sizeof(u64val));
559                 ret = -EOVERFLOW;
560         }
561         if (do_div(div64val, 256) != (u64val & 255)) {
562                 CERROR("do_div(%#llx,256) != %llu\n", u64val, u64val & 255);
563                 ret = -EOVERFLOW;
564         }
565         if (u64val >> 8 != div64val) {
566                 CERROR("do_div(%#llx,256) %llu != %llu\n",
567                        u64val, div64val, u64val >> 8);
568                 ret = -EOVERFLOW;
569         }
570         len = snprintf(buf, sizeof(buf), "%#llx", u64val);
571         if (len != 18) {
572                 CERROR("u64 hex wrong length! strlen(%s)=%d != 18\n", buf, len);
573                 ret = -EINVAL;
574         }
575         len = snprintf(buf, sizeof(buf), "%llu", u64val);
576         if (len != 20) {
577                 CERROR("u64 wrong length! strlen(%s)=%d != 20\n", buf, len);
578                 ret = -EINVAL;
579         }
580         len = snprintf(buf, sizeof(buf), "%lld", u64val);
581         if (len != 2) {
582                 CERROR("s64 wrong length! strlen(%s)=%d != 2\n", buf, len);
583                 ret = -EINVAL;
584         }
585         if ((u64val & ~PAGE_MASK) >= PAGE_SIZE) {
586                 CERROR("mask failed: u64val %llu >= %llu\n", u64val,
587                        (__u64)PAGE_SIZE);
588                 ret = -EINVAL;
589         }
590         if (ret)
591                 RETURN(ret);
592
593         /* invalid string */
594         if (!test_string_to_size_err("256B34", 256, "B", -EINVAL)) {
595                 CERROR("string_helpers: format should be number then units\n");
596                 ret = -EINVAL;
597         }
598         if (!test_string_to_size_err("132OpQ", 132, "B", -EINVAL)) {
599                 CERROR("string_helpers: invalid units should be rejected\n");
600                 ret = -EINVAL;
601         }
602         if (!test_string_to_size_err("1.82B", 1, "B", -EINVAL)) {
603                 CERROR("string_helpers: 'B' with '.' should be invalid\n");
604                 ret = -EINVAL;
605         }
606         if (test_string_to_size_one("343\n", 343, "B")) {
607                 CERROR("string_helpers: should ignore newline\n");
608                 ret = -EINVAL;
609         }
610         if (ret)
611                 RETURN(ret);
612
613         /* memparse unit handling */
614         ret = 0;
615         ret += test_string_to_size_one("0B", 0, "B");
616         ret += test_string_to_size_one("512B", 512, "B");
617         ret += test_string_to_size_one("1.067kB", 1067, "B");
618         ret += test_string_to_size_one("1.042KiB", 1067, "B");
619         ret += test_string_to_size_one("8", 8388608, "M");
620         ret += test_string_to_size_one("65536", 65536, "B");
621         ret += test_string_to_size_one("128", 131072, "K");
622         ret += test_string_to_size_one("1M", 1048576, "B");
623         ret += test_string_to_size_one("0.5T", 549755813888ULL, "T");
624         ret += test_string_to_size_one("256.5G", 275414777856ULL, "G");
625         if (ret)
626                 RETURN(ret);
627
628         /* string helper values */
629         ret += test_string_to_size_one("16", 16777216, "MiB");
630         ret += test_string_to_size_one("8.39MB", 8390000, "MiB");
631         ret += test_string_to_size_one("8.00MiB", 8388608, "MiB");
632         ret += test_string_to_size_one("256GB", 256000000000ULL, "GiB");
633         ret += test_string_to_size_one("238.731GiB", 256335459385ULL, "GiB");
634         if (ret)
635                 RETURN(ret);
636
637         /* huge values */
638         ret += test_string_to_size_one("0.4TB", 400000000000ULL, "TiB");
639         ret += test_string_to_size_one("12.5TiB", 13743895347200ULL, "TiB");
640         ret += test_string_to_size_one("2PB", 2000000000000000ULL, "PiB");
641         ret += test_string_to_size_one("16PiB", 18014398509481984ULL, "PiB");
642         if (ret)
643                 RETURN(ret);
644
645         /* huge values should overflow */
646         if (!test_string_to_size_err("1000EiB", 0, "EiB", -EOVERFLOW)) {
647                 CERROR("string_helpers: failed to detect binary overflow\n");
648                 ret = -EINVAL;
649         }
650         if (!test_string_to_size_err("1000EB", 0, "EiB", -EOVERFLOW)) {
651                 CERROR("string_helpers: failed to detect decimal overflow\n");
652                 ret = -EINVAL;
653         }
654
655         return ret;
656 }
657
658 static int __init obdclass_init(void)
659 {
660         int err;
661
662         LCONSOLE_INFO("Lustre: Build Version: "LUSTRE_VERSION_STRING"\n");
663
664         libcfs_kkuc_init();
665
666         err = obd_init_checks();
667         if (err)
668                 return err;
669
670 #ifdef CONFIG_PROC_FS
671         obd_memory = lprocfs_alloc_stats(OBD_STATS_NUM,
672                                          LPROCFS_STATS_FLAG_NONE |
673                                          LPROCFS_STATS_FLAG_IRQ_SAFE);
674         if (obd_memory == NULL) {
675                 CERROR("kmalloc of 'obd_memory' failed\n");
676                 return -ENOMEM;
677         }
678
679         lprocfs_counter_init(obd_memory, OBD_MEMORY_STAT,
680                              LPROCFS_CNTR_AVGMINMAX,
681                              "memused", "bytes");
682 #endif
683         err = obd_zombie_impexp_init();
684         if (err)
685                 goto cleanup_obd_memory;
686
687         err = class_handle_init();
688         if (err)
689                 goto cleanup_zombie_impexp;
690
691         err = misc_register(&obd_psdev);
692         if (err) {
693                 CERROR("cannot register OBD miscdevice: err = %d\n", err);
694                 goto cleanup_class_handle;
695         }
696
697         /* Default the dirty page cache cap to 1/2 of system memory.
698          * For clients with less memory, a larger fraction is needed
699          * for other purposes (mostly for BGL). */
700         if (cfs_totalram_pages() <= 512 << (20 - PAGE_SHIFT))
701                 obd_max_dirty_pages = cfs_totalram_pages() / 4;
702         else
703                 obd_max_dirty_pages = cfs_totalram_pages() / 2;
704
705         err = obd_init_caches();
706         if (err)
707                 goto cleanup_deregister;
708
709         err = class_procfs_init();
710         if (err)
711                 goto cleanup_caches;
712
713         err = lu_global_init();
714         if (err)
715                 goto cleanup_class_procfs;
716
717         err = cl_global_init();
718         if (err != 0)
719                 goto cleanup_lu_global;
720
721 #ifdef HAVE_SERVER_SUPPORT
722         err = dt_global_init();
723         if (err != 0)
724                 goto cleanup_cl_global;
725
726         err = lu_ucred_global_init();
727         if (err != 0)
728                 goto cleanup_dt_global;
729 #endif /* HAVE_SERVER_SUPPORT */
730
731         err = llog_info_init();
732         if (err)
733 #ifdef HAVE_SERVER_SUPPORT
734                 goto cleanup_lu_ucred_global;
735 #else /* !HAVE_SERVER_SUPPORT */
736                 goto cleanup_cl_global;
737 #endif /* HAVE_SERVER_SUPPORT */
738
739         err = lustre_register_fs();
740
741         /* simulate a late OOM situation now to require all
742          * alloc'ed/initialized resources to be freed */
743         if (OBD_FAIL_CHECK(OBD_FAIL_OBDCLASS_MODULE_LOAD)) {
744                 /* fake error but filesystem has been registered */
745                 lustre_unregister_fs();
746                 /* force error to ensure module will be unloaded/cleaned */
747                 err = -ENOMEM;
748         }
749
750         if (err)
751                 goto cleanup_llog_info;
752
753         return 0;
754
755 cleanup_llog_info:
756         llog_info_fini();
757
758 #ifdef HAVE_SERVER_SUPPORT
759 cleanup_lu_ucred_global:
760         lu_ucred_global_fini();
761
762 cleanup_dt_global:
763         dt_global_fini();
764 #endif /* HAVE_SERVER_SUPPORT */
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         lustre_unregister_fs();
831
832         misc_deregister(&obd_psdev);
833         llog_info_fini();
834 #ifdef HAVE_SERVER_SUPPORT
835         lu_ucred_global_fini();
836         dt_global_fini();
837 #endif /* HAVE_SERVER_SUPPORT */
838         cl_global_fini();
839         lu_global_fini();
840
841         obd_cleanup_caches();
842
843         class_procfs_clean();
844
845         class_handle_cleanup();
846         class_del_uuid(NULL); /* Delete all UUIDs. */
847         obd_zombie_impexp_stop();
848
849 #ifdef CONFIG_PROC_FS
850         memory_leaked = obd_memory_sum();
851         memory_max = obd_memory_max();
852
853         lprocfs_free_stats(&obd_memory);
854         /* the below message is checked in test-framework.sh check_mem_leak() */
855         CDEBUG((memory_leaked) ? D_ERROR : D_INFO,
856                "obd_memory max: %llu, leaked: %llu\n",
857                memory_max, memory_leaked);
858 #endif /* CONFIG_PROC_FS */
859
860         EXIT;
861 }
862
863 void obd_heat_clear(struct obd_heat_instance *instance, int count)
864 {
865         ENTRY;
866
867         memset(instance, 0, sizeof(*instance) * count);
868         RETURN_EXIT;
869 }
870 EXPORT_SYMBOL(obd_heat_clear);
871
872 /*
873  * The file heat is calculated for every time interval period I. The access
874  * frequency during each period is counted. The file heat is only recalculated
875  * at the end of a time period.  And a percentage of the former file heat is
876  * lost when recalculated. The recursion formula to calculate the heat of the
877  * file f is as follow:
878  *
879  * Hi+1(f) = (1-P)*Hi(f)+ P*Ci
880  *
881  * Where Hi is the heat value in the period between time points i*I and
882  * (i+1)*I; Ci is the access count in the period; the symbol P refers to the
883  * weight of Ci. The larger the value the value of P is, the more influence Ci
884  * has on the file heat.
885  */
886 void obd_heat_decay(struct obd_heat_instance *instance,  __u64 time_second,
887                     unsigned int weight, unsigned int period_second)
888 {
889         u64 second;
890
891         ENTRY;
892
893         if (instance->ohi_time_second > time_second) {
894                 obd_heat_clear(instance, 1);
895                 RETURN_EXIT;
896         }
897
898         if (instance->ohi_time_second == 0)
899                 RETURN_EXIT;
900
901         for (second = instance->ohi_time_second + period_second;
902              second < time_second;
903              second += period_second) {
904                 instance->ohi_heat = instance->ohi_heat *
905                                 (256 - weight) / 256 +
906                                 instance->ohi_count * weight / 256;
907                 instance->ohi_count = 0;
908                 instance->ohi_time_second = second;
909         }
910         RETURN_EXIT;
911 }
912 EXPORT_SYMBOL(obd_heat_decay);
913
914 __u64 obd_heat_get(struct obd_heat_instance *instance, unsigned int time_second,
915                    unsigned int weight, unsigned int period_second)
916 {
917         ENTRY;
918
919         obd_heat_decay(instance, time_second, weight, period_second);
920
921         if (instance->ohi_count == 0)
922                 RETURN(instance->ohi_heat);
923
924         RETURN(instance->ohi_heat * (256 - weight) / 256 +
925                instance->ohi_count * weight / 256);
926 }
927 EXPORT_SYMBOL(obd_heat_get);
928
929 void obd_heat_add(struct obd_heat_instance *instance,
930                   unsigned int time_second,  __u64 count,
931                   unsigned int weight, unsigned int period_second)
932 {
933         ENTRY;
934
935         obd_heat_decay(instance, time_second, weight, period_second);
936         if (instance->ohi_time_second == 0) {
937                 instance->ohi_time_second = time_second;
938                 instance->ohi_heat = 0;
939                 instance->ohi_count = count;
940         } else {
941                 instance->ohi_count += count;
942         }
943         RETURN_EXIT;
944 }
945 EXPORT_SYMBOL(obd_heat_add);
946
947 MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
948 MODULE_DESCRIPTION("Lustre Class Driver");
949 MODULE_VERSION(LUSTRE_VERSION_STRING);
950 MODULE_LICENSE("GPL");
951
952 module_init(obdclass_init);
953 module_exit(obdclass_exit);