2c9cfaeda0cea36b9ac1fa8ae0b022629ccf83dd
[dragonfly.git] / sys / netgraph7 / dragonfly.c
1 #include <netgraph7/ng_message.h>
2
3 #include <sys/malloc.h>
4 #include <sys/linker.h>
5 #include <sys/thread2.h>
6 #include <sys/vnode.h>
7
8 #include "dragonfly.h"
9
10 /* Temporary lock stuff. */
11 #include <sys/lock.h>
12 /* End Temporary lock stuff. */
13
14 int
15 linker_api_available(void)
16 {
17         /* linker_* API won't work without a process context */
18         if (curproc == NULL)
19                 return 0;
20         /*
21          * nlookup_init() relies on namei_oc to be initialized,
22          * but it's not when the netgraph module is loaded during boot.
23          */
24         if (namei_oc == NULL)
25                 return 0;
26         return 1;
27 }
28
29
30
31 /* Locking stuff. */
32
33
34 int
35 lockstatus_owned(struct lock *lkp, struct thread *td)
36 {
37         int lock_type = 0;
38
39         if (lkp->lk_exclusivecount != 0) {
40                 if (td == NULL || lkp->lk_lockholder == td)
41                         lock_type = LK_EXCLUSIVE;
42                 else
43                         lock_type = LK_EXCLOTHER;
44         } else if (lkp->lk_sharecount != 0) {
45                 lock_type = LK_SHARED;
46         }
47         return (lock_type);
48 }
49
50 /*
51  * Atomically drop a lockmgr lock and go to sleep. The lock is reacquired
52  * before returning from this function. Passes on the value returned by
53  * tsleep().
54  */
55 int
56 lock_sleep(void *ident, int flags, const char *wmesg, int timo,
57                 struct lock *lk)
58 {
59         int err, mode;
60
61         mode = lockstatus_owned(lk, curthread);
62         KKASSERT((mode == LK_EXCLUSIVE) || (mode == LK_SHARED));
63
64         crit_enter();
65         tsleep_interlock(ident, flags);
66         lockmgr(lk, LK_RELEASE);
67         err = tsleep(ident, flags, wmesg, timo);
68         crit_exit();
69         lockmgr(lk, mode);
70         return err;
71 }