]> git.proxmox.com Git - mirror_spl.git/blob - module/splat/splat-internal.h
eff8a9e74f989dede23bd218eb99d6e49c549756
[mirror_spl.git] / module / splat / splat-internal.h
1 /*****************************************************************************\
2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 * Copyright (C) 2007 The Regents of the University of California.
4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5 * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
6 * UCRL-CODE-235197
7 *
8 * This file is part of the SPL, Solaris Porting Layer.
9 * For details, see <http://zfsonlinux.org/>.
10 *
11 * The SPL is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
15 *
16 * The SPL is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
23 \*****************************************************************************/
24
25 #ifndef _SPLAT_INTERNAL_H
26 #define _SPLAT_INTERNAL_H
27
28 #include "splat-ctl.h"
29 #include <sys/mutex.h>
30
31 #define SPLAT_SUBSYSTEM_INIT(type) \
32 ({ splat_subsystem_t *_sub_; \
33 \
34 _sub_ = (splat_subsystem_t *)splat_##type##_init(); \
35 if (_sub_ == NULL) { \
36 printk(KERN_ERR "splat: Error initializing: " #type "\n"); \
37 } else { \
38 spin_lock(&splat_module_lock); \
39 list_add_tail(&(_sub_->subsystem_list), \
40 &splat_module_list); \
41 spin_unlock(&splat_module_lock); \
42 } \
43 })
44
45 #define SPLAT_SUBSYSTEM_FINI(type) \
46 ({ splat_subsystem_t *_sub_, *_tmp_; \
47 int _id_, _flag_ = 0; \
48 \
49 _id_ = splat_##type##_id(); \
50 spin_lock(&splat_module_lock); \
51 list_for_each_entry_safe(_sub_, _tmp_, &splat_module_list, \
52 subsystem_list) { \
53 if (_sub_->desc.id == _id_) { \
54 list_del_init(&(_sub_->subsystem_list)); \
55 spin_unlock(&splat_module_lock); \
56 splat_##type##_fini(_sub_); \
57 spin_lock(&splat_module_lock); \
58 _flag_ = 1; \
59 } \
60 } \
61 spin_unlock(&splat_module_lock); \
62 \
63 if (!_flag_) \
64 printk(KERN_ERR "splat: Error finalizing: " #type "\n"); \
65 })
66
67 #define SPLAT_TEST_INIT(sub, n, d, tid, func) \
68 ({ splat_test_t *_test_; \
69 \
70 _test_ = (splat_test_t *)kmalloc(sizeof(*_test_), GFP_KERNEL); \
71 if (_test_ == NULL) { \
72 printk(KERN_ERR "splat: Error initializing: " n "/" #tid" \n");\
73 } else { \
74 memset(_test_, 0, sizeof(*_test_)); \
75 strncpy(_test_->desc.name, n, SPLAT_NAME_SIZE-1); \
76 strncpy(_test_->desc.desc, d, SPLAT_DESC_SIZE-1); \
77 _test_->desc.id = tid; \
78 _test_->test = func; \
79 INIT_LIST_HEAD(&(_test_->test_list)); \
80 spin_lock(&((sub)->test_lock)); \
81 list_add_tail(&(_test_->test_list),&((sub)->test_list));\
82 spin_unlock(&((sub)->test_lock)); \
83 } \
84 })
85
86 #define SPLAT_TEST_FINI(sub, tid) \
87 ({ splat_test_t *_test_, *_tmp_; \
88 int _flag_ = 0; \
89 \
90 spin_lock(&((sub)->test_lock)); \
91 list_for_each_entry_safe(_test_, _tmp_, \
92 &((sub)->test_list), test_list) { \
93 if (_test_->desc.id == tid) { \
94 list_del_init(&(_test_->test_list)); \
95 _flag_ = 1; \
96 } \
97 } \
98 spin_unlock(&((sub)->test_lock)); \
99 \
100 if (!_flag_) \
101 printk(KERN_ERR "splat: Error finalizing: " #tid "\n"); \
102 })
103
104 typedef int (*splat_test_func_t)(struct file *, void *);
105
106 typedef struct splat_test {
107 struct list_head test_list;
108 splat_user_t desc;
109 splat_test_func_t test;
110 } splat_test_t;
111
112 typedef struct splat_subsystem {
113 struct list_head subsystem_list;/* List had to chain entries */
114 splat_user_t desc;
115 spinlock_t test_lock;
116 struct list_head test_list;
117 } splat_subsystem_t;
118
119 #define SPLAT_INFO_BUFFER_SIZE 65536
120 #define SPLAT_INFO_BUFFER_REDZONE 256
121
122 typedef struct splat_info {
123 kmutex_t info_lock;
124 int info_size;
125 char *info_buffer;
126 char *info_head; /* Internal kernel use only */
127 } splat_info_t;
128
129 #define sym2str(sym) (char *)(#sym)
130
131 #define splat_print(file, format, args...) \
132 ({ splat_info_t *_info_ = (splat_info_t *)file->private_data; \
133 int _rc_; \
134 \
135 ASSERT(_info_); \
136 ASSERT(_info_->info_buffer); \
137 \
138 mutex_enter(&_info_->info_lock); \
139 \
140 /* Don't allow the kernel to start a write in the red zone */ \
141 if ((int)(_info_->info_head - _info_->info_buffer) > \
142 (SPLAT_INFO_BUFFER_SIZE - SPLAT_INFO_BUFFER_REDZONE)) { \
143 _rc_ = -EOVERFLOW; \
144 } else { \
145 _rc_ = sprintf(_info_->info_head, format, args); \
146 if (_rc_ >= 0) \
147 _info_->info_head += _rc_; \
148 } \
149 \
150 mutex_exit(&_info_->info_lock); \
151 _rc_; \
152 })
153
154 #define splat_vprint(file, test, format, args...) \
155 splat_print(file, "%*s: " format, SPLAT_NAME_SIZE, test, args)
156
157 #define splat_locked_test(lock, test) \
158 ({ \
159 int _rc_; \
160 spin_lock(lock); \
161 _rc_ = (test) ? 1 : 0; \
162 spin_unlock(lock); \
163 _rc_; \
164 })
165
166 splat_subsystem_t *splat_condvar_init(void);
167 splat_subsystem_t *splat_kmem_init(void);
168 splat_subsystem_t *splat_mutex_init(void);
169 splat_subsystem_t *splat_krng_init(void);
170 splat_subsystem_t *splat_rwlock_init(void);
171 splat_subsystem_t *splat_taskq_init(void);
172 splat_subsystem_t *splat_thread_init(void);
173 splat_subsystem_t *splat_time_init(void);
174 splat_subsystem_t *splat_vnode_init(void);
175 splat_subsystem_t *splat_kobj_init(void);
176 splat_subsystem_t *splat_atomic_init(void);
177 splat_subsystem_t *splat_list_init(void);
178 splat_subsystem_t *splat_generic_init(void);
179 splat_subsystem_t *splat_cred_init(void);
180 splat_subsystem_t *splat_zlib_init(void);
181 splat_subsystem_t *splat_linux_init(void);
182
183 void splat_condvar_fini(splat_subsystem_t *);
184 void splat_kmem_fini(splat_subsystem_t *);
185 void splat_mutex_fini(splat_subsystem_t *);
186 void splat_krng_fini(splat_subsystem_t *);
187 void splat_rwlock_fini(splat_subsystem_t *);
188 void splat_taskq_fini(splat_subsystem_t *);
189 void splat_thread_fini(splat_subsystem_t *);
190 void splat_time_fini(splat_subsystem_t *);
191 void splat_vnode_fini(splat_subsystem_t *);
192 void splat_kobj_fini(splat_subsystem_t *);
193 void splat_atomic_fini(splat_subsystem_t *);
194 void splat_list_fini(splat_subsystem_t *);
195 void splat_generic_fini(splat_subsystem_t *);
196 void splat_cred_fini(splat_subsystem_t *);
197 void splat_zlib_fini(splat_subsystem_t *);
198 void splat_linux_fini(splat_subsystem_t *);
199
200 int splat_condvar_id(void);
201 int splat_kmem_id(void);
202 int splat_mutex_id(void);
203 int splat_krng_id(void);
204 int splat_rwlock_id(void);
205 int splat_taskq_id(void);
206 int splat_thread_id(void);
207 int splat_time_id(void);
208 int splat_vnode_id(void);
209 int splat_kobj_id(void);
210 int splat_atomic_id(void);
211 int splat_list_id(void);
212 int splat_generic_id(void);
213 int splat_cred_id(void);
214 int splat_zlib_id(void);
215 int splat_linux_id(void);
216
217 #endif /* _SPLAT_INTERNAL_H */