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