1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2002 Cluster File Systems, Inc.
5 * Author: Phil Schwan <phil@clusterfs.com>
7 * This file is part of Lustre, http://www.lustre.org.
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.
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.
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.
22 * Darwin porting library
23 * Make things easy to port
25 #define DEBUG_SUBSYSTEM S_PORTALS
27 #include <mach/mach_types.h>
29 #include <netinet/in.h>
30 #include <netinet/tcp.h>
33 #include <sys/vnode.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>
42 #include <libcfs/libcfs.h>
43 #include <libcfs/kp30.h>
45 void *darwin_current_journal_info = NULL;
46 int darwin_current_cap_effective = -1;
49 * cfs pseudo device, actually pseudo char device in darwin
51 #define KPORTAL_MAJOR -1
53 kern_return_t cfs_psdev_register(cfs_psdev_t *dev) {
54 dev->index = cdevsw_add(KPORTAL_MAJOR, dev->devsw);
56 printf("portal_init: failed to allocate a major number!\n");
59 dev->handle = devfs_make_node(makedev (dev->index, 0),
61 GID_WHEEL, 0666, (char *)dev->name, 0);
65 kern_return_t cfs_psdev_deregister(cfs_psdev_t *dev) {
66 devfs_remove(dev->handle);
67 cdevsw_remove(dev->index, dev->devsw);
72 * KPortal symbol register / unregister support
74 static struct rw_semaphore cfs_symbol_lock;
75 struct list_head cfs_symbol_list;
78 cfs_symbol_get(const char *name)
80 struct list_head *walker;
81 struct cfs_symbol *sym = NULL;
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)) {
91 up_read(&cfs_symbol_lock);
98 cfs_symbol_put(const char *name)
100 struct list_head *walker;
101 struct cfs_symbol *sym = NULL;
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)) {
108 LASSERT(sym->ref >= 0);
112 up_read(&cfs_symbol_lock);
113 LASSERT(sym != NULL);
119 cfs_symbol_register(const char *name, const void *value)
121 struct list_head *walker;
122 struct cfs_symbol *sym = NULL;
123 struct cfs_symbol *new = NULL;
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;
129 CFS_INIT_LIST_HEAD(&new->sym_list);
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);
137 return KERN_NAME_EXISTS;
141 list_add_tail(&new->sym_list, &cfs_symbol_list);
142 up_write(&cfs_symbol_lock);
148 cfs_symbol_unregister(const char *name)
150 struct list_head *walker;
151 struct list_head *nxt;
152 struct cfs_symbol *sym = NULL;
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);
164 up_write(&cfs_symbol_lock);
172 struct list_head *walker;
173 struct cfs_symbol *sym = NULL;
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);
182 up_write(&cfs_symbol_lock);
187 * Register sysctl table
189 cfs_sysctl_table_header_t *
190 register_cfs_sysctl_table (cfs_sysctl_table_t *table, int arg)
192 cfs_sysctl_table_t item;
195 while ((item = table[i++]) != NULL) {
196 sysctl_register_oid(item);
202 * Unregister sysctl table
205 unregister_cfs_sysctl_table (cfs_sysctl_table_header_t *table) {
207 cfs_sysctl_table_t item;
209 while ((item = table[i++]) != NULL) {
210 sysctl_unregister_oid(item);
215 struct kernel_thread_arg cfs_thread_arg;
218 cfs_thread_agent_init()
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;
227 cfs_thread_agent (void)
229 cfs_thread_t func = NULL;
232 thread_arg_recv(&cfs_thread_arg, func, arg);
233 printf("entry of thread agent (func: %08lx).\n", (void *)func);
234 assert(func != NULL);
236 printf("thread agent exit. (func: %08lx)\n", (void *)func);
237 (void) thread_terminate(current_act());
241 cfs_kernel_thread(cfs_thread_t func, void *arg, int flag)
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)
254 void lustre_cone_in(boolean_t *state, funnel_t **cone)
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);
263 void lustre_cone_ex(boolean_t state, funnel_t *cone)
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);
271 void lustre_net_in(boolean_t *state, funnel_t **cone)
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);
280 void lustre_net_ex(boolean_t state, funnel_t *cone)
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);
289 void cfs_waitq_init(struct cfs_waitq *waitq)
291 ksleep_chan_init(&waitq->wq_ksleep_chan);
294 void cfs_waitlink_init(struct cfs_waitlink *link)
296 ksleep_link_init(&link->wl_ksleep_link);
299 void cfs_waitq_add(struct cfs_waitq *waitq, struct cfs_waitlink *link)
301 link->wl_waitq = waitq;
302 ksleep_add(&waitq->wq_ksleep_chan, &link->wl_ksleep_link);
305 void cfs_waitq_add_exclusive(struct cfs_waitq *waitq,
306 struct cfs_waitlink *link)
308 link->wl_waitq = waitq;
309 link->wl_ksleep_link.flags |= KSLEEP_EXCLUSIVE;
310 ksleep_add(&waitq->wq_ksleep_chan, &link->wl_ksleep_link);
313 void cfs_waitq_forward(struct cfs_waitlink *link,
314 struct cfs_waitq *waitq)
316 link->wl_ksleep_link.forward = &waitq->wq_ksleep_chan;
319 void cfs_waitq_del(struct cfs_waitq *waitq,
320 struct cfs_waitlink *link)
322 ksleep_del(&waitq->wq_ksleep_chan, &link->wl_ksleep_link);
325 int cfs_waitq_active(struct cfs_waitq *waitq)
330 void cfs_waitq_signal(struct cfs_waitq *waitq)
332 ksleep_wake(&waitq->wq_ksleep_chan);
335 void cfs_waitq_signal_nr(struct cfs_waitq *waitq, int nr)
337 ksleep_wake_nr(&waitq->wq_ksleep_chan, nr);
340 void cfs_waitq_broadcast(struct cfs_waitq *waitq)
342 ksleep_wake_all(&waitq->wq_ksleep_chan);
345 void cfs_waitq_wait(struct cfs_waitlink *link)
347 ksleep_wait(&link->wl_waitq->wq_ksleep_chan);
350 cfs_duration_t cfs_waitq_timedwait(struct cfs_waitlink *link,
351 cfs_duration_t timeout)
353 CDEBUG(D_TRACE, "timeout: %llu\n", (long long unsigned)timeout);
354 return ksleep_timedwait(&link->chan->c, timeout);
357 typedef void (*ktimer_func_t)(void *);
358 void cfs_timer_init(cfs_timer_t *t, void (* func)(unsigned long), void *arg)
360 ktimer_init(&t->t, (ktimer_func_t)func, arg);
363 void cfs_timer_done(struct cfs_timer *t)
368 void cfs_timer_arm(struct cfs_timer *t, cfs_time_t deadline)
370 ktimer_arm(&t->t, deadline);
373 void cfs_timer_disarm(struct cfs_timer *t)
375 ktimer_disarm(&t->t);
378 int cfs_timer_is_armed(struct cfs_timer *t)
380 return ktimer_is_armed(&t->t);
383 cfs_time_t cfs_timer_deadline(struct cfs_timer *t)
385 return ktimer_deadline(&t->t);
389 libcfs_arch_init(void)
391 init_rwsem(&cfs_symbol_lock);
392 CFS_INIT_LIST_HEAD(&cfs_symbol_list);
393 cfs_thread_agent_init();
398 libcfs_arch_cleanup(void)