]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/lustre/lustre/libcfs/module.c
staging/lustre/libcfs: Adjust NULL comparison codestyle
[karo-tx-linux.git] / drivers / staging / lustre / lustre / libcfs / module.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.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, 2015 Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/mm.h>
39 #include <linux/string.h>
40 #include <linux/stat.h>
41 #include <linux/errno.h>
42 #include <linux/unistd.h>
43 #include <net/sock.h>
44 #include <linux/uio.h>
45
46 #include <linux/uaccess.h>
47
48 #include <linux/fs.h>
49 #include <linux/file.h>
50 #include <linux/list.h>
51
52 #include <linux/sysctl.h>
53 #include <linux/debugfs.h>
54
55 # define DEBUG_SUBSYSTEM S_LNET
56
57 #include "../../include/linux/libcfs/libcfs.h"
58 #include <asm/div64.h>
59
60 #include "../../include/linux/libcfs/libcfs_crypto.h"
61 #include "../../include/linux/lnet/lib-lnet.h"
62 #include "../../include/linux/lnet/lnet.h"
63 #include "tracefile.h"
64
65 MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
66 MODULE_DESCRIPTION("Portals v3.1");
67 MODULE_LICENSE("GPL");
68
69 static struct dentry *lnet_debugfs_root;
70
71 /* called when opening /dev/device */
72 static int libcfs_psdev_open(unsigned long flags, void *args)
73 {
74         try_module_get(THIS_MODULE);
75         return 0;
76 }
77
78 /* called when closing /dev/device */
79 static int libcfs_psdev_release(unsigned long flags, void *args)
80 {
81         module_put(THIS_MODULE);
82         return 0;
83 }
84
85 static DECLARE_RWSEM(ioctl_list_sem);
86 static LIST_HEAD(ioctl_list);
87
88 int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand)
89 {
90         int rc = 0;
91
92         down_write(&ioctl_list_sem);
93         if (!list_empty(&hand->item))
94                 rc = -EBUSY;
95         else
96                 list_add_tail(&hand->item, &ioctl_list);
97         up_write(&ioctl_list_sem);
98
99         return rc;
100 }
101 EXPORT_SYMBOL(libcfs_register_ioctl);
102
103 int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand)
104 {
105         int rc = 0;
106
107         down_write(&ioctl_list_sem);
108         if (list_empty(&hand->item))
109                 rc = -ENOENT;
110         else
111                 list_del_init(&hand->item);
112         up_write(&ioctl_list_sem);
113
114         return rc;
115 }
116 EXPORT_SYMBOL(libcfs_deregister_ioctl);
117
118 static int libcfs_ioctl_int(struct cfs_psdev_file *pfile, unsigned long cmd,
119                             void __user *arg, struct libcfs_ioctl_data *data)
120 {
121         int err = -EINVAL;
122
123         switch (cmd) {
124         case IOC_LIBCFS_CLEAR_DEBUG:
125                 libcfs_debug_clear_buffer();
126                 return 0;
127         /*
128          * case IOC_LIBCFS_PANIC:
129          * Handled in arch/cfs_module.c
130          */
131         case IOC_LIBCFS_MARK_DEBUG:
132                 if (!data->ioc_inlbuf1 ||
133                     data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0')
134                         return -EINVAL;
135                 libcfs_debug_mark_buffer(data->ioc_inlbuf1);
136                 return 0;
137
138         default: {
139                 struct libcfs_ioctl_handler *hand;
140
141                 err = -EINVAL;
142                 down_read(&ioctl_list_sem);
143                 list_for_each_entry(hand, &ioctl_list, item) {
144                         err = hand->handle_ioctl(cmd, data);
145                         if (err != -EINVAL) {
146                                 if (err == 0)
147                                         err = libcfs_ioctl_popdata(arg,
148                                                         data, sizeof(*data));
149                                 break;
150                         }
151                 }
152                 up_read(&ioctl_list_sem);
153                 break;
154         }
155         }
156
157         return err;
158 }
159
160 static int libcfs_ioctl(struct cfs_psdev_file *pfile, unsigned long cmd,
161                         void __user *arg)
162 {
163         char    *buf;
164         struct libcfs_ioctl_data *data;
165         int err = 0;
166
167         LIBCFS_ALLOC_GFP(buf, 1024, GFP_KERNEL);
168         if (!buf)
169                 return -ENOMEM;
170
171         /* 'cmd' and permissions get checked in our arch-specific caller */
172         if (libcfs_ioctl_getdata(buf, buf + 800, arg)) {
173                 CERROR("PORTALS ioctl: data error\n");
174                 err = -EINVAL;
175                 goto out;
176         }
177         data = (struct libcfs_ioctl_data *)buf;
178
179         err = libcfs_ioctl_int(pfile, cmd, arg, data);
180
181 out:
182         LIBCFS_FREE(buf, 1024);
183         return err;
184 }
185
186 struct cfs_psdev_ops libcfs_psdev_ops = {
187         libcfs_psdev_open,
188         libcfs_psdev_release,
189         NULL,
190         NULL,
191         libcfs_ioctl
192 };
193
194 static int proc_call_handler(void *data, int write, loff_t *ppos,
195                 void __user *buffer, size_t *lenp,
196                 int (*handler)(void *data, int write,
197                 loff_t pos, void __user *buffer, int len))
198 {
199         int rc = handler(data, write, *ppos, buffer, *lenp);
200
201         if (rc < 0)
202                 return rc;
203
204         if (write) {
205                 *ppos += *lenp;
206         } else {
207                 *lenp = rc;
208                 *ppos += rc;
209         }
210         return 0;
211 }
212
213 static int __proc_dobitmasks(void *data, int write,
214                              loff_t pos, void __user *buffer, int nob)
215 {
216         const int     tmpstrlen = 512;
217         char     *tmpstr;
218         int        rc;
219         unsigned int *mask = data;
220         int        is_subsys = (mask == &libcfs_subsystem_debug) ? 1 : 0;
221         int        is_printk = (mask == &libcfs_printk) ? 1 : 0;
222
223         rc = cfs_trace_allocate_string_buffer(&tmpstr, tmpstrlen);
224         if (rc < 0)
225                 return rc;
226
227         if (!write) {
228                 libcfs_debug_mask2str(tmpstr, tmpstrlen, *mask, is_subsys);
229                 rc = strlen(tmpstr);
230
231                 if (pos >= rc) {
232                         rc = 0;
233                 } else {
234                         rc = cfs_trace_copyout_string(buffer, nob,
235                                                       tmpstr + pos, "\n");
236                 }
237         } else {
238                 rc = cfs_trace_copyin_string(tmpstr, tmpstrlen, buffer, nob);
239                 if (rc < 0) {
240                         kfree(tmpstr);
241                         return rc;
242                 }
243
244                 rc = libcfs_debug_str2mask(mask, tmpstr, is_subsys);
245                 /* Always print LBUG/LASSERT to console, so keep this mask */
246                 if (is_printk)
247                         *mask |= D_EMERG;
248         }
249
250         kfree(tmpstr);
251         return rc;
252 }
253
254 static int proc_dobitmasks(struct ctl_table *table, int write,
255                            void __user *buffer, size_t *lenp, loff_t *ppos)
256 {
257         return proc_call_handler(table->data, write, ppos, buffer, lenp,
258                                  __proc_dobitmasks);
259 }
260
261 static int __proc_dump_kernel(void *data, int write,
262                               loff_t pos, void __user *buffer, int nob)
263 {
264         if (!write)
265                 return 0;
266
267         return cfs_trace_dump_debug_buffer_usrstr(buffer, nob);
268 }
269
270 static int proc_dump_kernel(struct ctl_table *table, int write,
271                             void __user *buffer, size_t *lenp, loff_t *ppos)
272 {
273         return proc_call_handler(table->data, write, ppos, buffer, lenp,
274                                  __proc_dump_kernel);
275 }
276
277 static int __proc_daemon_file(void *data, int write,
278                               loff_t pos, void __user *buffer, int nob)
279 {
280         if (!write) {
281                 int len = strlen(cfs_tracefile);
282
283                 if (pos >= len)
284                         return 0;
285
286                 return cfs_trace_copyout_string(buffer, nob,
287                                                 cfs_tracefile + pos, "\n");
288         }
289
290         return cfs_trace_daemon_command_usrstr(buffer, nob);
291 }
292
293 static int proc_daemon_file(struct ctl_table *table, int write,
294                             void __user *buffer, size_t *lenp, loff_t *ppos)
295 {
296         return proc_call_handler(table->data, write, ppos, buffer, lenp,
297                                  __proc_daemon_file);
298 }
299
300 static int libcfs_force_lbug(struct ctl_table *table, int write,
301                              void __user *buffer,
302                              size_t *lenp, loff_t *ppos)
303 {
304         if (write)
305                 LBUG();
306         return 0;
307 }
308
309 static int proc_fail_loc(struct ctl_table *table, int write,
310                          void __user *buffer,
311                          size_t *lenp, loff_t *ppos)
312 {
313         int rc;
314         long old_fail_loc = cfs_fail_loc;
315
316         rc = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
317         if (old_fail_loc != cfs_fail_loc)
318                 wake_up(&cfs_race_waitq);
319         return rc;
320 }
321
322 static int __proc_cpt_table(void *data, int write,
323                             loff_t pos, void __user *buffer, int nob)
324 {
325         char *buf = NULL;
326         int   len = 4096;
327         int   rc  = 0;
328
329         if (write)
330                 return -EPERM;
331
332         LASSERT(cfs_cpt_table);
333
334         while (1) {
335                 LIBCFS_ALLOC(buf, len);
336                 if (!buf)
337                         return -ENOMEM;
338
339                 rc = cfs_cpt_table_print(cfs_cpt_table, buf, len);
340                 if (rc >= 0)
341                         break;
342
343                 if (rc == -EFBIG) {
344                         LIBCFS_FREE(buf, len);
345                         len <<= 1;
346                         continue;
347                 }
348                 goto out;
349         }
350
351         if (pos >= rc) {
352                 rc = 0;
353                 goto out;
354         }
355
356         rc = cfs_trace_copyout_string(buffer, nob, buf + pos, NULL);
357  out:
358         if (buf)
359                 LIBCFS_FREE(buf, len);
360         return rc;
361 }
362
363 static int proc_cpt_table(struct ctl_table *table, int write,
364                            void __user *buffer, size_t *lenp, loff_t *ppos)
365 {
366         return proc_call_handler(table->data, write, ppos, buffer, lenp,
367                                  __proc_cpt_table);
368 }
369
370 static struct ctl_table lnet_table[] = {
371         {
372                 .procname = "debug",
373                 .data     = &libcfs_debug,
374                 .maxlen   = sizeof(int),
375                 .mode     = 0644,
376                 .proc_handler = &proc_dobitmasks,
377         },
378         {
379                 .procname = "subsystem_debug",
380                 .data     = &libcfs_subsystem_debug,
381                 .maxlen   = sizeof(int),
382                 .mode     = 0644,
383                 .proc_handler = &proc_dobitmasks,
384         },
385         {
386                 .procname = "printk",
387                 .data     = &libcfs_printk,
388                 .maxlen   = sizeof(int),
389                 .mode     = 0644,
390                 .proc_handler = &proc_dobitmasks,
391         },
392         {
393                 .procname = "cpu_partition_table",
394                 .maxlen   = 128,
395                 .mode     = 0444,
396                 .proc_handler = &proc_cpt_table,
397         },
398
399         {
400                 .procname = "upcall",
401                 .data     = lnet_upcall,
402                 .maxlen   = sizeof(lnet_upcall),
403                 .mode     = 0644,
404                 .proc_handler = &proc_dostring,
405         },
406         {
407                 .procname = "debug_log_upcall",
408                 .data     = lnet_debug_log_upcall,
409                 .maxlen   = sizeof(lnet_debug_log_upcall),
410                 .mode     = 0644,
411                 .proc_handler = &proc_dostring,
412         },
413         {
414                 .procname = "catastrophe",
415                 .data     = &libcfs_catastrophe,
416                 .maxlen   = sizeof(int),
417                 .mode     = 0444,
418                 .proc_handler = &proc_dointvec,
419         },
420         {
421                 .procname = "dump_kernel",
422                 .maxlen   = 256,
423                 .mode     = 0200,
424                 .proc_handler = &proc_dump_kernel,
425         },
426         {
427                 .procname = "daemon_file",
428                 .mode     = 0644,
429                 .maxlen   = 256,
430                 .proc_handler = &proc_daemon_file,
431         },
432         {
433                 .procname = "force_lbug",
434                 .data     = NULL,
435                 .maxlen   = 0,
436                 .mode     = 0200,
437                 .proc_handler = &libcfs_force_lbug
438         },
439         {
440                 .procname = "fail_loc",
441                 .data     = &cfs_fail_loc,
442                 .maxlen   = sizeof(cfs_fail_loc),
443                 .mode     = 0644,
444                 .proc_handler = &proc_fail_loc
445         },
446         {
447                 .procname = "fail_val",
448                 .data     = &cfs_fail_val,
449                 .maxlen   = sizeof(int),
450                 .mode     = 0644,
451                 .proc_handler = &proc_dointvec
452         },
453         {
454         }
455 };
456
457 static const struct lnet_debugfs_symlink_def lnet_debugfs_symlinks[] = {
458         { "console_ratelimit",
459           "/sys/module/libcfs/parameters/libcfs_console_ratelimit"},
460         { "debug_path",
461           "/sys/module/libcfs/parameters/libcfs_debug_file_path"},
462         { "panic_on_lbug",
463           "/sys/module/libcfs/parameters/libcfs_panic_on_lbug"},
464         { "libcfs_console_backoff",
465           "/sys/module/libcfs/parameters/libcfs_console_backoff"},
466         { "debug_mb",
467           "/sys/module/libcfs/parameters/libcfs_debug_mb"},
468         { "console_min_delay_centisecs",
469           "/sys/module/libcfs/parameters/libcfs_console_min_delay"},
470         { "console_max_delay_centisecs",
471           "/sys/module/libcfs/parameters/libcfs_console_max_delay"},
472         {},
473 };
474
475 static ssize_t lnet_debugfs_read(struct file *filp, char __user *buf,
476                                  size_t count, loff_t *ppos)
477 {
478         struct ctl_table *table = filp->private_data;
479         int error;
480
481         error = table->proc_handler(table, 0, (void __user *)buf, &count, ppos);
482         if (!error)
483                 error = count;
484
485         return error;
486 }
487
488 static ssize_t lnet_debugfs_write(struct file *filp, const char __user *buf,
489                                   size_t count, loff_t *ppos)
490 {
491         struct ctl_table *table = filp->private_data;
492         int error;
493
494         error = table->proc_handler(table, 1, (void __user *)buf, &count, ppos);
495         if (!error)
496                 error = count;
497
498         return error;
499 }
500
501 static const struct file_operations lnet_debugfs_file_operations_rw = {
502         .open           = simple_open,
503         .read           = lnet_debugfs_read,
504         .write          = lnet_debugfs_write,
505         .llseek         = default_llseek,
506 };
507
508 static const struct file_operations lnet_debugfs_file_operations_ro = {
509         .open           = simple_open,
510         .read           = lnet_debugfs_read,
511         .llseek         = default_llseek,
512 };
513
514 static const struct file_operations lnet_debugfs_file_operations_wo = {
515         .open           = simple_open,
516         .write          = lnet_debugfs_write,
517         .llseek         = default_llseek,
518 };
519
520 static const struct file_operations *lnet_debugfs_fops_select(umode_t mode)
521 {
522         if (!(mode & S_IWUGO))
523                 return &lnet_debugfs_file_operations_ro;
524
525         if (!(mode & S_IRUGO))
526                 return &lnet_debugfs_file_operations_wo;
527
528         return &lnet_debugfs_file_operations_rw;
529 }
530
531 void lustre_insert_debugfs(struct ctl_table *table,
532                            const struct lnet_debugfs_symlink_def *symlinks)
533 {
534         if (!lnet_debugfs_root)
535                 lnet_debugfs_root = debugfs_create_dir("lnet", NULL);
536
537         /* Even if we cannot create, just ignore it altogether) */
538         if (IS_ERR_OR_NULL(lnet_debugfs_root))
539                 return;
540
541         /* We don't save the dentry returned in next two calls, because
542          * we don't call debugfs_remove() but rather remove_recursive()
543          */
544         for (; table->procname; table++)
545                 debugfs_create_file(table->procname, table->mode,
546                                     lnet_debugfs_root, table,
547                                     lnet_debugfs_fops_select(table->mode));
548
549         for (; symlinks && symlinks->name; symlinks++)
550                 debugfs_create_symlink(symlinks->name, lnet_debugfs_root,
551                                        symlinks->target);
552
553 }
554 EXPORT_SYMBOL_GPL(lustre_insert_debugfs);
555
556 static void lustre_remove_debugfs(void)
557 {
558         debugfs_remove_recursive(lnet_debugfs_root);
559
560         lnet_debugfs_root = NULL;
561 }
562
563 static int init_libcfs_module(void)
564 {
565         int rc;
566
567         rc = libcfs_debug_init(5 * 1024 * 1024);
568         if (rc < 0) {
569                 pr_err("LustreError: libcfs_debug_init: %d\n", rc);
570                 return rc;
571         }
572
573         rc = cfs_cpu_init();
574         if (rc != 0)
575                 goto cleanup_debug;
576
577         rc = misc_register(&libcfs_dev);
578         if (rc) {
579                 CERROR("misc_register: error %d\n", rc);
580                 goto cleanup_cpu;
581         }
582
583         rc = cfs_wi_startup();
584         if (rc) {
585                 CERROR("initialize workitem: error %d\n", rc);
586                 goto cleanup_deregister;
587         }
588
589         /* max to 4 threads, should be enough for rehash */
590         rc = min(cfs_cpt_weight(cfs_cpt_table, CFS_CPT_ANY), 4);
591         rc = cfs_wi_sched_create("cfs_rh", cfs_cpt_table, CFS_CPT_ANY,
592                                  rc, &cfs_sched_rehash);
593         if (rc != 0) {
594                 CERROR("Startup workitem scheduler: error: %d\n", rc);
595                 goto cleanup_deregister;
596         }
597
598         rc = cfs_crypto_register();
599         if (rc) {
600                 CERROR("cfs_crypto_register: error %d\n", rc);
601                 goto cleanup_wi;
602         }
603
604         lustre_insert_debugfs(lnet_table, lnet_debugfs_symlinks);
605
606         CDEBUG(D_OTHER, "portals setup OK\n");
607         return 0;
608  cleanup_wi:
609         cfs_wi_shutdown();
610  cleanup_deregister:
611         misc_deregister(&libcfs_dev);
612 cleanup_cpu:
613         cfs_cpu_fini();
614  cleanup_debug:
615         libcfs_debug_cleanup();
616         return rc;
617 }
618
619 static void exit_libcfs_module(void)
620 {
621         int rc;
622
623         lustre_remove_debugfs();
624
625         if (cfs_sched_rehash) {
626                 cfs_wi_sched_destroy(cfs_sched_rehash);
627                 cfs_sched_rehash = NULL;
628         }
629
630         cfs_crypto_unregister();
631         cfs_wi_shutdown();
632
633         misc_deregister(&libcfs_dev);
634
635         cfs_cpu_fini();
636
637         rc = libcfs_debug_cleanup();
638         if (rc)
639                 pr_err("LustreError: libcfs_debug_cleanup: %d\n", rc);
640 }
641
642 MODULE_VERSION("1.0.0");
643
644 module_init(init_libcfs_module);
645 module_exit(exit_libcfs_module);