fix: proc: decouple proc from VFS with "struct proc_ops" (v5.6)
[lttng-modules.git] / probes / lttng.c
1 /*
2 * lttng.c
3 *
4 * LTTng logger ABI
5 *
6 * Copyright (C) 2008-2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; only
11 * version 2.1 of the License.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <linux/module.h>
24 #include <linux/tracepoint.h>
25 #include <linux/uaccess.h>
26 #include <linux/gfp.h>
27 #include <linux/fs.h>
28 #include <linux/proc_fs.h>
29 #include <linux/slab.h>
30 #include <linux/mm.h>
31 #include <wrapper/vmalloc.h>
32 #include <lttng-events.h>
33
34 #define TP_MODULE_NOAUTOLOAD
35 #define LTTNG_PACKAGE_BUILD
36 #define CREATE_TRACE_POINTS
37 #define TRACE_INCLUDE_PATH instrumentation/events/lttng-module
38 #define TRACE_INCLUDE_FILE lttng
39 #define LTTNG_INSTRUMENTATION
40
41 #include <instrumentation/events/lttng-module/lttng.h>
42
43 /* Events written through logger are truncated at 1024 bytes */
44 #define LTTNG_LOGGER_COUNT_MAX 1024
45 #define LTTNG_LOGGER_FILE "lttng-logger"
46
47 DEFINE_TRACE(lttng_logger);
48
49 static struct proc_dir_entry *lttng_logger_dentry;
50
51 /**
52 * lttng_logger_write - write a userspace string into the trace system
53 * @file: file pointer
54 * @user_buf: user string
55 * @count: length to copy
56 * @ppos: file position
57 *
58 * Copy a userspace string into a trace event named "lttng:logger".
59 * Copies at most @count bytes into the event "msg" dynamic array.
60 * Truncates the count at LTTNG_LOGGER_COUNT_MAX. Returns the number of
61 * bytes copied from the source.
62 * Return -1 on error, with EFAULT errno.
63 */
64 static
65 ssize_t lttng_logger_write(struct file *file, const char __user *user_buf,
66 size_t count, loff_t *ppos)
67 {
68 int nr_pages = 1, i;
69 unsigned long uaddr = (unsigned long) user_buf;
70 struct page *pages[2];
71 ssize_t written;
72 int ret;
73
74 /* Truncate count */
75 if (unlikely(count > LTTNG_LOGGER_COUNT_MAX))
76 count = LTTNG_LOGGER_COUNT_MAX;
77
78 /* How many pages are we dealing with ? */
79 if (unlikely((uaddr & PAGE_MASK) != ((uaddr + count) & PAGE_MASK)))
80 nr_pages = 2;
81
82 /* Pin userspace pages */
83 ret = get_user_pages_fast(uaddr, nr_pages, 0, pages);
84 if (unlikely(ret < nr_pages)) {
85 if (ret > 0) {
86 BUG_ON(ret != 1);
87 put_page(pages[0]);
88 }
89 written = -EFAULT;
90 goto end;
91 }
92
93 /* Trace the event */
94 trace_lttng_logger(user_buf, count);
95 written = count;
96 *ppos += written;
97
98 for (i = 0; i < nr_pages; i++)
99 put_page(pages[i]);
100 end:
101 return written;
102 }
103
104 static const struct file_operations lttng_logger_operations = {
105 .write = lttng_logger_write,
106 };
107
108 /*
109 * Linux 5.6 introduced a separate proc_ops struct for /proc operations
110 * to decouple it from the vfs.
111 */
112 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
113 static const struct proc_ops lttng_logger_proc_ops = {
114 .proc_write = lttng_logger_write,
115 };
116 #else
117 #define lttng_logger_proc_ops lttng_logger_operations
118 #endif
119
120 int __init lttng_logger_init(void)
121 {
122 int ret = 0;
123
124 wrapper_vmalloc_sync_all();
125 lttng_logger_dentry = proc_create_data(LTTNG_LOGGER_FILE,
126 S_IRUGO | S_IWUGO, NULL,
127 &lttng_logger_proc_ops, NULL);
128 if (!lttng_logger_dentry) {
129 printk(KERN_ERR "Error creating LTTng logger file\n");
130 ret = -ENOMEM;
131 goto error;
132 }
133 ret = __lttng_events_init__lttng();
134 if (ret)
135 goto error_events;
136 return ret;
137
138 error_events:
139 remove_proc_entry("lttng-logger", NULL);
140 error:
141 return ret;
142 }
143
144 void lttng_logger_exit(void)
145 {
146 __lttng_events_exit__lttng();
147 if (lttng_logger_dentry)
148 remove_proc_entry("lttng-logger", NULL);
149 }
This page took 0.031583 seconds and 4 git commands to generate.