Commit | Line | Data |
---|---|---|
7633c773 MJ |
1 | /* SPDX-License-Identifier: (GPL-2.0-only OR LGPL-2.1-only) |
2 | * | |
3 | * wrapper/genhd.c | |
4 | * | |
5 | * Wrapper around disk_part_iter_(init|next|exit). Using KALLSYMS to get the | |
6 | * addresses when available, else we need to have a kernel that exports this | |
7 | * function to GPL modules. This export was removed in 5.12. | |
8 | * | |
9 | * Copyright (C) 2021 Michael Jeanson <mjeanson@efficios.com> | |
10 | */ | |
11 | ||
12 | #include <lttng/kernel-version.h> | |
13 | #include <linux/module.h> | |
14 | #include <wrapper/genhd.h> | |
15 | ||
16 | #if (defined(CONFIG_KALLSYMS) && \ | |
17 | (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,12,0))) | |
18 | ||
19 | #include <wrapper/kallsyms.h> | |
20 | ||
21 | static | |
22 | void (*disk_part_iter_init_sym)(struct disk_part_iter *piter, struct gendisk *disk, | |
23 | unsigned int flags); | |
24 | ||
25 | static | |
26 | LTTNG_DISK_PART_TYPE *(*disk_part_iter_next_sym)(struct disk_part_iter *piter); | |
27 | ||
28 | static | |
29 | void (*disk_part_iter_exit_sym)(struct disk_part_iter *piter); | |
30 | ||
31 | /* | |
32 | * This wrapper has an 'int' return type instead of the original 'void', to be | |
33 | * able to report the symbol lookup failure to the caller. | |
34 | * | |
35 | * Return 0 on success, -1 on error. | |
36 | */ | |
37 | int wrapper_disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk, | |
38 | unsigned int flags) | |
39 | { | |
40 | if (!disk_part_iter_init_sym) | |
41 | disk_part_iter_init_sym = (void *) kallsyms_lookup_funcptr("disk_part_iter_init"); | |
42 | ||
43 | if (disk_part_iter_init_sym) { | |
44 | disk_part_iter_init_sym(piter, disk, flags); | |
45 | } else { | |
46 | printk_once(KERN_WARNING "LTTng: disk_part_iter_init symbol lookup failed.\n"); | |
47 | return -1; | |
48 | } | |
49 | return 0; | |
50 | } | |
51 | EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_init); | |
52 | ||
53 | LTTNG_DISK_PART_TYPE *wrapper_disk_part_iter_next(struct disk_part_iter *piter) | |
54 | { | |
55 | if (!disk_part_iter_next_sym) | |
56 | disk_part_iter_next_sym = (void *) kallsyms_lookup_funcptr("disk_part_iter_next"); | |
57 | ||
58 | if (disk_part_iter_next_sym) { | |
59 | return disk_part_iter_next_sym(piter); | |
60 | } else { | |
61 | printk_once(KERN_WARNING "LTTng: disk_part_iter_next symbol lookup failed.\n"); | |
62 | return NULL; | |
63 | } | |
64 | } | |
65 | EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_next); | |
66 | ||
67 | /* | |
68 | * We don't return an error on symbol lookup failure here because there is | |
69 | * nothing the caller can do to cleanup the iterator. | |
70 | */ | |
71 | void wrapper_disk_part_iter_exit(struct disk_part_iter *piter) | |
72 | { | |
73 | if (!disk_part_iter_exit_sym) | |
74 | disk_part_iter_exit_sym = (void *) kallsyms_lookup_funcptr("disk_part_iter_exit"); | |
75 | ||
76 | if (disk_part_iter_exit_sym) { | |
77 | disk_part_iter_exit_sym(piter); | |
78 | } else { | |
79 | printk_once(KERN_WARNING "LTTng: disk_part_iter_exit symbol lookup failed.\n"); | |
80 | } | |
81 | } | |
82 | EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_exit); | |
83 | ||
84 | #else | |
85 | ||
86 | /* | |
87 | * This wrapper has an 'int' return type instead of the original 'void', so the | |
88 | * kallsyms variant can report the symbol lookup failure to the caller. | |
89 | * | |
90 | * This variant always succeeds and returns 0. | |
91 | */ | |
92 | int wrapper_disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk, | |
93 | unsigned int flags) | |
94 | { | |
95 | disk_part_iter_init(piter, disk, flags); | |
96 | return 0; | |
97 | } | |
98 | EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_init); | |
99 | ||
100 | LTTNG_DISK_PART_TYPE *wrapper_disk_part_iter_next(struct disk_part_iter *piter) | |
101 | { | |
102 | return disk_part_iter_next(piter); | |
103 | } | |
104 | EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_next); | |
105 | ||
106 | void wrapper_disk_part_iter_exit(struct disk_part_iter *piter) | |
107 | { | |
108 | disk_part_iter_exit(piter); | |
109 | } | |
110 | EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_exit); | |
111 | #endif |