Whamcloud - gitweb
85437693524d641080f7c6661271b17ea5525503
[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_err(value, expect, def_unit, __rc)                 \
528 ({                                                                             \
529         u64 __size;                                                            \
530         int __ret;                                                             \
531                                                                                \
532         BUILD_BUG_ON(sizeof(value) >= 23);                                     \
533         __ret = sysfs_memparse(value, sizeof(value) - 1, &__size, def_unit);   \
534         if (__ret != __rc)                                                     \
535                 CERROR("string_helper: parsing '%s' expect rc %d != got %d\n", \
536                        value, __rc, __ret);                                    \
537         else if (!__ret && (u64)expect != __size)                              \
538                 CERROR("string_helper: parsing '%s' expect %llu != got %llu\n",\
539                        value, (u64)expect, __size);                            \
540         __ret;                                                                 \
541 })
542 #define test_string_to_size_one(value, expect, def_unit)                       \
543         test_string_to_size_err(value, expect, def_unit, 0)
544
545 static int __init obd_init_checks(void)
546 {
547         __u64 u64val, div64val;
548         char buf[64];
549         int len, ret = 0;
550
551         CDEBUG(D_INFO, "OBD_OBJECT_EOF = %#llx\n", (__u64)OBD_OBJECT_EOF);
552
553         u64val = OBD_OBJECT_EOF;
554         CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
555         if (u64val != OBD_OBJECT_EOF) {
556                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
557                        u64val, (int)sizeof(u64val));
558                 ret = -EINVAL;
559         }
560         len = snprintf(buf, sizeof(buf), "%#llx", u64val);
561         if (len != 18) {
562                 CERROR("u64 hex wrong length, strlen(%s)=%d != 18\n", buf, len);
563                 ret = -EINVAL;
564         }
565
566         div64val = OBD_OBJECT_EOF;
567         CDEBUG(D_INFO, "u64val OBD_OBJECT_EOF = %#llx\n", u64val);
568         if (u64val != OBD_OBJECT_EOF) {
569                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
570                        u64val, (int)sizeof(u64val));
571                 ret = -EOVERFLOW;
572         }
573         if (u64val >> 8 != OBD_OBJECT_EOF >> 8) {
574                 CERROR("__u64 %#llx(%d) != 0xffffffffffffffff\n",
575                        u64val, (int)sizeof(u64val));
576                 ret = -EOVERFLOW;
577         }
578         if (do_div(div64val, 256) != (u64val & 255)) {
579                 CERROR("do_div(%#llx,256) != %llu\n", u64val, u64val & 255);
580                 ret = -EOVERFLOW;
581         }
582         if (u64val >> 8 != div64val) {
583                 CERROR("do_div(%#llx,256) %llu != %llu\n",
584                        u64val, div64val, u64val >> 8);
585                 ret = -EOVERFLOW;
586         }
587         len = snprintf(buf, sizeof(buf), "%#llx", u64val);
588         if (len != 18) {
589                 CERROR("u64 hex wrong length! strlen(%s)=%d != 18\n", buf, len);
590                 ret = -EINVAL;
591         }
592         len = snprintf(buf, sizeof(buf), "%llu", u64val);
593         if (len != 20) {
594                 CERROR("u64 wrong length! strlen(%s)=%d != 20\n", buf, len);
595                 ret = -EINVAL;
596         }
597         len = snprintf(buf, sizeof(buf), "%lld", u64val);
598         if (len != 2) {
599                 CERROR("s64 wrong length! strlen(%s)=%d != 2\n", buf, len);
600                 ret = -EINVAL;
601         }
602         if ((u64val & ~PAGE_MASK) >= PAGE_SIZE) {
603                 CERROR("mask failed: u64val %llu >= %llu\n", u64val,
604                        (__u64)PAGE_SIZE);
605                 ret = -EINVAL;
606         }
607         if (ret)
608                 RETURN(ret);
609
610         /* invalid string */
611         if (!test_string_to_size_err("256B34", 256, "B", -EINVAL)) {
612                 CERROR("string_helpers: format should be number then units\n");
613                 ret = -EINVAL;
614         }
615         if (!test_string_to_size_err("132OpQ", 132, "B", -EINVAL)) {
616                 CERROR("string_helpers: invalid units should be rejected\n");
617                 ret = -EINVAL;
618         }
619         if (!test_string_to_size_err("1.82B", 1, "B", -EINVAL)) {
620                 CERROR("string_helpers: 'B' with '.' should be invalid\n");
621                 ret = -EINVAL;
622         }
623         if (test_string_to_size_one("343\n", 343, "B")) {
624                 CERROR("string_helpers: should ignore newline\n");
625                 ret = -EINVAL;
626         }
627         if (ret)
628                 RETURN(ret);
629
630         /* memparse unit handling */
631         ret = 0;
632         ret += test_string_to_size_one("0B", 0, "B");
633         ret += test_string_to_size_one("512B", 512, "B");
634         ret += test_string_to_size_one("1.067kB", 1067, "B");
635         ret += test_string_to_size_one("1.042KiB", 1067, "B");
636         ret += test_string_to_size_one("8", 8388608, "M");
637         ret += test_string_to_size_one("65536", 65536, "B");
638         ret += test_string_to_size_one("128", 131072, "K");
639         ret += test_string_to_size_one("1M", 1048576, "B");
640         ret += test_string_to_size_one("0.5T", 549755813888ULL, "T");
641         ret += test_string_to_size_one("256.5G", 275414777856ULL, "G");
642         if (ret)
643                 RETURN(ret);
644
645         /* string helper values */
646         ret += test_string_to_size_one("16", 16777216, "MiB");
647         ret += test_string_to_size_one("8.39MB", 8390000, "MiB");
648         ret += test_string_to_size_one("8.00MiB", 8388608, "MiB");
649         ret += test_string_to_size_one("256GB", 256000000000ULL, "GiB");
650         ret += test_string_to_size_one("238.731GiB", 256335459385ULL, "GiB");
651         if (ret)
652                 RETURN(ret);
653
654         /* huge values */
655         ret += test_string_to_size_one("0.4TB", 400000000000ULL, "TiB");
656         ret += test_string_to_size_one("12.5TiB", 13743895347200ULL, "TiB");
657         ret += test_string_to_size_one("2PB", 2000000000000000ULL, "PiB");
658         ret += test_string_to_size_one("16PiB", 18014398509481984ULL, "PiB");
659         if (ret)
660                 RETURN(ret);
661
662         /* huge values should overflow */
663         if (!test_string_to_size_err("1000EiB", 0, "EiB", -EOVERFLOW)) {
664                 CERROR("string_helpers: failed to detect binary overflow\n");
665                 ret = -EINVAL;
666         }
667         if (!test_string_to_size_err("1000EB", 0, "EiB", -EOVERFLOW)) {
668                 CERROR("string_helpers: failed to detect decimal overflow\n");
669                 ret = -EINVAL;
670         }
671
672         return ret;
673 }
674
675 static int __init obdclass_init(void)
676 {
677         int err;
678
679         LCONSOLE_INFO("Lustre: Build Version: "LUSTRE_VERSION_STRING"\n");
680
681         libcfs_kkuc_init();
682
683         err = obd_init_checks();
684         if (err)
685                 return err;
686
687 #ifdef CONFIG_PROC_FS
688         obd_memory = lprocfs_alloc_stats(OBD_STATS_NUM,
689                                          LPROCFS_STATS_FLAG_NONE |
690                                          LPROCFS_STATS_FLAG_IRQ_SAFE);
691         if (obd_memory == NULL) {
692                 CERROR("kmalloc of 'obd_memory' failed\n");
693                 return -ENOMEM;
694         }
695
696         lprocfs_counter_init(obd_memory, OBD_MEMORY_STAT,
697                              LPROCFS_CNTR_AVGMINMAX,
698                              "memused", "bytes");
699 #endif
700         err = obd_zombie_impexp_init();
701         if (err)
702                 goto cleanup_obd_memory;
703
704         err = class_handle_init();
705         if (err)
706                 goto cleanup_zombie_impexp;
707
708         err = misc_register(&obd_psdev);
709         if (err) {
710                 CERROR("cannot register OBD miscdevice: err = %d\n", err);
711                 goto cleanup_class_handle;
712         }
713
714         /* Default the dirty page cache cap to 1/2 of system memory.
715          * For clients with less memory, a larger fraction is needed
716          * for other purposes (mostly for BGL). */
717         if (cfs_totalram_pages() <= 512 << (20 - PAGE_SHIFT))
718                 obd_max_dirty_pages = cfs_totalram_pages() / 4;
719         else
720                 obd_max_dirty_pages = cfs_totalram_pages() / 2;
721
722         err = obd_init_caches();
723         if (err)
724                 goto cleanup_deregister;
725
726         err = class_procfs_init();
727         if (err)
728                 goto cleanup_caches;
729
730         err = lu_global_init();
731         if (err)
732                 goto cleanup_class_procfs;
733
734         err = cl_global_init();
735         if (err != 0)
736                 goto cleanup_lu_global;
737
738 #ifdef HAVE_SERVER_SUPPORT
739         err = dt_global_init();
740         if (err != 0)
741                 goto cleanup_cl_global;
742
743         err = lu_ucred_global_init();
744         if (err != 0)
745                 goto cleanup_dt_global;
746 #endif /* HAVE_SERVER_SUPPORT */
747
748         err = llog_info_init();
749         if (err)
750 #ifdef HAVE_SERVER_SUPPORT
751                 goto cleanup_lu_ucred_global;
752 #else /* !HAVE_SERVER_SUPPORT */
753                 goto cleanup_cl_global;
754 #endif /* HAVE_SERVER_SUPPORT */
755
756         err = lustre_register_fs();
757
758         /* simulate a late OOM situation now to require all
759          * alloc'ed/initialized resources to be freed */
760         if (OBD_FAIL_CHECK(OBD_FAIL_OBDCLASS_MODULE_LOAD)) {
761                 /* fake error but filesystem has been registered */
762                 lustre_unregister_fs();
763                 /* force error to ensure module will be unloaded/cleaned */
764                 err = -ENOMEM;
765         }
766
767         if (err)
768                 goto cleanup_llog_info;
769
770         return 0;
771
772 cleanup_llog_info:
773         llog_info_fini();
774
775 #ifdef HAVE_SERVER_SUPPORT
776 cleanup_lu_ucred_global:
777         lu_ucred_global_fini();
778
779 cleanup_dt_global:
780         dt_global_fini();
781 #endif /* HAVE_SERVER_SUPPORT */
782
783 cleanup_cl_global:
784         cl_global_fini();
785
786 cleanup_lu_global:
787         lu_global_fini();
788
789 cleanup_class_procfs:
790         class_procfs_clean();
791
792 cleanup_caches:
793         obd_cleanup_caches();
794
795 cleanup_deregister:
796         misc_deregister(&obd_psdev);
797
798 cleanup_class_handle:
799         class_handle_cleanup();
800
801 cleanup_zombie_impexp:
802         obd_zombie_impexp_stop();
803
804 cleanup_obd_memory:
805 #ifdef CONFIG_PROC_FS
806         lprocfs_free_stats(&obd_memory);
807 #endif
808
809         return err;
810 }
811
812 void obd_update_maxusage(void)
813 {
814         __u64 max;
815
816         max = obd_memory_sum();
817
818         spin_lock(&obd_updatemax_lock);
819         if (max > obd_max_alloc)
820                 obd_max_alloc = max;
821         spin_unlock(&obd_updatemax_lock);
822 }
823 EXPORT_SYMBOL(obd_update_maxusage);
824
825 #ifdef CONFIG_PROC_FS
826 __u64 obd_memory_max(void)
827 {
828         __u64 ret;
829
830         obd_update_maxusage();
831         spin_lock(&obd_updatemax_lock);
832         ret = obd_max_alloc;
833         spin_unlock(&obd_updatemax_lock);
834
835         return ret;
836 }
837 #endif /* CONFIG_PROC_FS */
838
839 static void __exit obdclass_exit(void)
840 {
841 #ifdef CONFIG_PROC_FS
842         __u64 memory_leaked;
843         __u64 memory_max;
844 #endif /* CONFIG_PROC_FS */
845         ENTRY;
846
847         lustre_unregister_fs();
848
849         misc_deregister(&obd_psdev);
850         llog_info_fini();
851 #ifdef HAVE_SERVER_SUPPORT
852         lu_ucred_global_fini();
853         dt_global_fini();
854 #endif /* HAVE_SERVER_SUPPORT */
855         cl_global_fini();
856         lu_global_fini();
857
858         obd_cleanup_caches();
859
860         class_procfs_clean();
861
862         class_handle_cleanup();
863         class_del_uuid(NULL); /* Delete all UUIDs. */
864         obd_zombie_impexp_stop();
865
866 #ifdef CONFIG_PROC_FS
867         memory_leaked = obd_memory_sum();
868         memory_max = obd_memory_max();
869
870         lprocfs_free_stats(&obd_memory);
871         /* the below message is checked in test-framework.sh check_mem_leak() */
872         CDEBUG((memory_leaked) ? D_ERROR : D_INFO,
873                "obd_memory max: %llu, leaked: %llu\n",
874                memory_max, memory_leaked);
875 #endif /* CONFIG_PROC_FS */
876
877         EXIT;
878 }
879
880 void obd_heat_clear(struct obd_heat_instance *instance, int count)
881 {
882         ENTRY;
883
884         memset(instance, 0, sizeof(*instance) * count);
885         RETURN_EXIT;
886 }
887 EXPORT_SYMBOL(obd_heat_clear);
888
889 /*
890  * The file heat is calculated for every time interval period I. The access
891  * frequency during each period is counted. The file heat is only recalculated
892  * at the end of a time period.  And a percentage of the former file heat is
893  * lost when recalculated. The recursion formula to calculate the heat of the
894  * file f is as follow:
895  *
896  * Hi+1(f) = (1-P)*Hi(f)+ P*Ci
897  *
898  * Where Hi is the heat value in the period between time points i*I and
899  * (i+1)*I; Ci is the access count in the period; the symbol P refers to the
900  * weight of Ci. The larger the value the value of P is, the more influence Ci
901  * has on the file heat.
902  */
903 void obd_heat_decay(struct obd_heat_instance *instance,  __u64 time_second,
904                     unsigned int weight, unsigned int period_second)
905 {
906         u64 second;
907
908         ENTRY;
909
910         if (instance->ohi_time_second > time_second) {
911                 obd_heat_clear(instance, 1);
912                 RETURN_EXIT;
913         }
914
915         if (instance->ohi_time_second == 0)
916                 RETURN_EXIT;
917
918         for (second = instance->ohi_time_second + period_second;
919              second < time_second;
920              second += period_second) {
921                 instance->ohi_heat = instance->ohi_heat *
922                                 (256 - weight) / 256 +
923                                 instance->ohi_count * weight / 256;
924                 instance->ohi_count = 0;
925                 instance->ohi_time_second = second;
926         }
927         RETURN_EXIT;
928 }
929 EXPORT_SYMBOL(obd_heat_decay);
930
931 __u64 obd_heat_get(struct obd_heat_instance *instance, unsigned int time_second,
932                    unsigned int weight, unsigned int period_second)
933 {
934         ENTRY;
935
936         obd_heat_decay(instance, time_second, weight, period_second);
937
938         if (instance->ohi_count == 0)
939                 RETURN(instance->ohi_heat);
940
941         RETURN(instance->ohi_heat * (256 - weight) / 256 +
942                instance->ohi_count * weight / 256);
943 }
944 EXPORT_SYMBOL(obd_heat_get);
945
946 void obd_heat_add(struct obd_heat_instance *instance,
947                   unsigned int time_second,  __u64 count,
948                   unsigned int weight, unsigned int period_second)
949 {
950         ENTRY;
951
952         obd_heat_decay(instance, time_second, weight, period_second);
953         if (instance->ohi_time_second == 0) {
954                 instance->ohi_time_second = time_second;
955                 instance->ohi_heat = 0;
956                 instance->ohi_count = count;
957         } else {
958                 instance->ohi_count += count;
959         }
960         RETURN_EXIT;
961 }
962 EXPORT_SYMBOL(obd_heat_add);
963
964 MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
965 MODULE_DESCRIPTION("Lustre Class Driver");
966 MODULE_VERSION(LUSTRE_VERSION_STRING);
967 MODULE_LICENSE("GPL");
968
969 module_init(obdclass_init);
970 module_exit(obdclass_exit);