Whamcloud - gitweb
add some real userspace definitions for CDEBUG et al
[fs/lustre-release.git] / lnet / libcfs / darwin / darwin-prim.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2002 Cluster File Systems, Inc.
5  * Author: Phil Schwan <phil@clusterfs.com>
6  *
7  * This file is part of Lustre, http://www.lustre.org.
8  *
9  * Lustre is free software; you can redistribute it and/or
10  * modify it under the terms of version 2 of the GNU General Public
11  * License as published by the Free Software Foundation.
12  *
13  * Lustre 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
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Lustre; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * Darwin porting library
23  * Make things easy to port
24  */
25 #define DEBUG_SUBSYSTEM S_PORTALS
26
27 #include <mach/mach_types.h>
28 #include <string.h>
29 #include <netinet/in.h>
30 #include <netinet/tcp.h>
31 #include <sys/file.h>
32 #include <sys/conf.h>
33 #include <sys/vnode.h>
34 #include <sys/uio.h>
35 #include <sys/filedesc.h>
36 #include <sys/namei.h>
37 #include <miscfs/devfs/devfs.h>
38 #include <kern/kalloc.h>
39 #include <kern/zalloc.h>
40 #include <kern/thread.h>
41
42 #include <libcfs/libcfs.h>
43 #include <libcfs/kp30.h>
44
45 void    *darwin_current_journal_info = NULL;
46 int     darwin_current_cap_effective = -1;
47
48 /* 
49  * cfs pseudo device, actually pseudo char device in darwin 
50  */
51 #define KPORTAL_MAJOR  -1
52
53 kern_return_t  cfs_psdev_register(cfs_psdev_t *dev) {
54         dev->index = cdevsw_add(KPORTAL_MAJOR, dev->devsw);
55         if (dev->index < 0) {
56                 printf("portal_init: failed to allocate a major number!\n");
57                 return KERN_FAILURE;
58         }
59         dev->handle = devfs_make_node(makedev (dev->index, 0), 
60                                       DEVFS_CHAR, UID_ROOT, 
61                                       GID_WHEEL, 0666, (char *)dev->name, 0);
62         return KERN_SUCCESS;
63 }
64
65 kern_return_t  cfs_psdev_deregister(cfs_psdev_t *dev) {
66         devfs_remove(dev->handle);
67         cdevsw_remove(dev->index, dev->devsw);
68         return KERN_SUCCESS;
69 }
70
71 /* 
72  * KPortal symbol register / unregister support 
73  */
74 static struct rw_semaphore cfs_symbol_lock;
75 struct list_head           cfs_symbol_list;
76
77 void *
78 cfs_symbol_get(const char *name)
79 {
80         struct list_head    *walker;
81         struct cfs_symbol   *sym = NULL;
82
83         down_read(&cfs_symbol_lock);
84         list_for_each(walker, &cfs_symbol_list) {
85                 sym = list_entry (walker, struct cfs_symbol, sym_list);
86                 if (!strcmp(sym->name, name)) {
87                         sym->ref ++;
88                         break;
89                 }
90         } 
91         up_read(&cfs_symbol_lock);
92         if (sym != NULL) 
93                 return sym->value;
94         return NULL;
95 }
96
97 kern_return_t
98 cfs_symbol_put(const char *name)
99 {
100         struct list_head    *walker;
101         struct cfs_symbol   *sym = NULL;
102
103         down_read(&cfs_symbol_lock);
104         list_for_each(walker, &cfs_symbol_list) {
105                 sym = list_entry (walker, struct cfs_symbol, sym_list);
106                 if (!strcmp(sym->name, name)) {
107                         sym->ref --;
108                         LASSERT(sym->ref >= 0);
109                         break;
110                 }
111         } 
112         up_read(&cfs_symbol_lock);
113         LASSERT(sym != NULL);
114
115         return 0;
116 }
117
118 kern_return_t
119 cfs_symbol_register(const char *name, const void *value)
120 {
121         struct list_head    *walker;
122         struct cfs_symbol   *sym = NULL;
123         struct cfs_symbol   *new = NULL;
124
125         MALLOC(new, struct cfs_symbol *, sizeof(struct cfs_symbol), M_TEMP, M_WAITOK|M_ZERO);
126         strncpy(new->name, name, CFS_SYMBOL_LEN);
127         new->value = (void *)value;
128         new->ref = 0;
129         CFS_INIT_LIST_HEAD(&new->sym_list);
130
131         down_write(&cfs_symbol_lock);
132         list_for_each(walker, &cfs_symbol_list) {
133                 sym = list_entry (walker, struct cfs_symbol, sym_list);
134                 if (!strcmp(sym->name, name)) {
135                         up_write(&cfs_symbol_lock);
136                         FREE(new, M_TEMP);
137                         return KERN_NAME_EXISTS;
138                 }
139
140         }
141         list_add_tail(&new->sym_list, &cfs_symbol_list);
142         up_write(&cfs_symbol_lock);
143
144         return KERN_SUCCESS;
145 }
146
147 kern_return_t
148 cfs_symbol_unregister(const char *name)
149 {
150         struct list_head    *walker;
151         struct list_head    *nxt;
152         struct cfs_symbol   *sym = NULL;
153
154         down_write(&cfs_symbol_lock);
155         list_for_each_safe(walker, nxt, &cfs_symbol_list) {
156                 sym = list_entry (walker, struct cfs_symbol, sym_list);
157                 if (!strcmp(sym->name, name)) {
158                         LASSERT(sym->ref == 0);
159                         list_del (&sym->sym_list);
160                         FREE(sym, M_TEMP);
161                         break;
162                 }
163         }
164         up_write(&cfs_symbol_lock);
165
166         return KERN_SUCCESS;
167 }
168
169 void
170 cfs_symbol_clean()
171 {
172         struct list_head    *walker;
173         struct cfs_symbol   *sym = NULL;
174
175         down_write(&cfs_symbol_lock);
176         list_for_each(walker, &cfs_symbol_list) {
177                 sym = list_entry (walker, struct cfs_symbol, sym_list);
178                 LASSERT(sym->ref == 0);
179                 list_del (&sym->sym_list);
180                 FREE(sym, M_TEMP);
181         }
182         up_write(&cfs_symbol_lock);
183         return;
184 }
185
186 /* 
187  * Register sysctl table
188  */
189 cfs_sysctl_table_header_t *
190 register_cfs_sysctl_table (cfs_sysctl_table_t *table, int arg)
191 {
192         cfs_sysctl_table_t      item;
193         int i = 0;
194
195         while ((item = table[i++]) != NULL) {
196                 sysctl_register_oid(item); 
197         }
198         return table;
199 }
200
201 /*
202  * Unregister sysctl table
203  */
204 void
205 unregister_cfs_sysctl_table (cfs_sysctl_table_header_t *table) {
206         int i = 0;
207         cfs_sysctl_table_t      item;
208
209         while ((item = table[i++]) != NULL) {
210                 sysctl_unregister_oid(item); 
211         }
212         return;
213 }
214
215 struct kernel_thread_arg cfs_thread_arg;
216
217 void
218 cfs_thread_agent_init()
219
220         set_targ_stat(&cfs_thread_arg, THREAD_ARG_FREE); 
221         spin_lock_init(&cfs_thread_arg.lock);        
222         cfs_thread_arg.arg = NULL;                       
223         cfs_thread_arg.func = NULL;       
224 }
225
226 void
227 cfs_thread_agent (void) 
228 {
229         cfs_thread_t           func = NULL;
230         void                   *arg = NULL;
231
232         thread_arg_recv(&cfs_thread_arg, func, arg);
233         printf("entry of thread agent (func: %08lx).\n", (void *)func);
234         assert(func != NULL);
235         func(arg);
236         printf("thread agent exit. (func: %08lx)\n", (void *)func);
237         (void) thread_terminate(current_act());
238 }
239
240 int
241 cfs_kernel_thread(cfs_thread_t  func, void *arg, int flag)
242
243         int ret = 0;   
244         thread_t th = NULL;  
245                                                 
246         thread_arg_hold(&cfs_thread_arg, func, arg); 
247         th = kernel_thread(kernel_task, cfs_thread_agent);  
248         thread_arg_release(&cfs_thread_arg);      
249         if (th == THREAD_NULL) 
250                 ret = -1;  
251         return ret;
252 }
253
254 void lustre_cone_in(boolean_t *state, funnel_t **cone)
255 {
256         *cone = thread_funnel_get();
257         if (*cone == network_flock)
258                 thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
259         else if (*cone == NULL)
260                 *state = thread_funnel_set(kernel_flock, TRUE);
261 }
262
263 void lustre_cone_ex(boolean_t state, funnel_t *cone)
264 {
265         if (cone == network_flock)
266                 thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
267         else if (cone == NULL)
268                 (void) thread_funnel_set(kernel_flock, state);
269 }
270
271 void lustre_net_in(boolean_t *state, funnel_t **cone)
272 {
273         *cone = thread_funnel_get();
274         if (*cone == kernel_flock)
275                 thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
276         else if (*cone == NULL)
277                 *state = thread_funnel_set(network_flock, TRUE);
278 }
279
280 void lustre_net_ex(boolean_t state, funnel_t *cone)
281 {
282         if (cone == kernel_flock)
283                 thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
284         else if (cone == NULL)
285                 (void) thread_funnel_set(network_flock, state);
286 }
287
288
289 void cfs_waitq_init(struct cfs_waitq *waitq)
290 {
291         ksleep_chan_init(&waitq->wq_ksleep_chan);
292 }
293
294 void cfs_waitlink_init(struct cfs_waitlink *link)
295 {
296         ksleep_link_init(&link->wl_ksleep_link);
297 }
298
299 void cfs_waitq_add(struct cfs_waitq *waitq, struct cfs_waitlink *link)
300
301         link->wl_waitq = waitq;
302         ksleep_add(&waitq->wq_ksleep_chan, &link->wl_ksleep_link);
303 }
304
305 void cfs_waitq_add_exclusive(struct cfs_waitq *waitq,
306                              struct cfs_waitlink *link)
307 {
308         link->wl_waitq = waitq;
309         link->wl_ksleep_link.flags |= KSLEEP_EXCLUSIVE;
310         ksleep_add(&waitq->wq_ksleep_chan, &link->wl_ksleep_link);
311 }
312
313 void cfs_waitq_forward(struct cfs_waitlink *link,
314                        struct cfs_waitq *waitq)
315 {
316         link->wl_ksleep_link.forward = &waitq->wq_ksleep_chan;
317 }
318
319 void cfs_waitq_del(struct cfs_waitq *waitq,
320                    struct cfs_waitlink *link)
321 {
322         ksleep_del(&waitq->wq_ksleep_chan, &link->wl_ksleep_link);
323 }
324
325 int cfs_waitq_active(struct cfs_waitq *waitq)
326 {
327         return (1);
328 }
329
330 void cfs_waitq_signal(struct cfs_waitq *waitq)
331 {
332         ksleep_wake(&waitq->wq_ksleep_chan);
333 }
334
335 void cfs_waitq_signal_nr(struct cfs_waitq *waitq, int nr)
336 {
337         ksleep_wake_nr(&waitq->wq_ksleep_chan, nr);
338 }
339
340 void cfs_waitq_broadcast(struct cfs_waitq *waitq)
341 {
342         ksleep_wake_all(&waitq->wq_ksleep_chan);
343 }
344
345 void cfs_waitq_wait(struct cfs_waitlink *link)
346
347         ksleep_wait(&link->wl_waitq->wq_ksleep_chan);
348 }
349
350 cfs_duration_t  cfs_waitq_timedwait(struct cfs_waitlink *link, 
351                                     cfs_duration_t timeout)
352
353         CDEBUG(D_TRACE, "timeout: %llu\n", (long long unsigned)timeout); 
354         return ksleep_timedwait(&link->chan->c, timeout);
355 }
356
357 typedef  void (*ktimer_func_t)(void *);
358 void cfs_timer_init(cfs_timer_t *t, void (* func)(unsigned long), void *arg)
359
360         ktimer_init(&t->t, (ktimer_func_t)func, arg);
361 }
362
363 void cfs_timer_done(struct cfs_timer *t)
364
365         ktimer_done(&t->t);
366 }
367
368 void cfs_timer_arm(struct cfs_timer *t, cfs_time_t deadline)
369
370         ktimer_arm(&t->t, deadline);
371 }
372
373 void cfs_timer_disarm(struct cfs_timer *t)
374
375         ktimer_disarm(&t->t);
376 }
377
378 int  cfs_timer_is_armed(struct cfs_timer *t)
379
380         return ktimer_is_armed(&t->t);
381 }
382
383 cfs_time_t cfs_timer_deadline(struct cfs_timer *t)
384
385         return ktimer_deadline(&t->t);
386 }
387
388 int
389 libcfs_arch_init(void)
390 {
391         init_rwsem(&cfs_symbol_lock);
392         CFS_INIT_LIST_HEAD(&cfs_symbol_list);
393         cfs_thread_agent_init();
394         return 0;
395 }
396
397 void
398 libcfs_arch_cleanup(void)
399 {
400         cfs_symbol_clean();
401 }
402