afs: alloc openafs_lck_grp before osi_Init() on darwin
[openafs.git] / src / afs / DARWIN / osi_module.c
1 #include <afsconfig.h>
2 #include "afs/param.h"
3
4 #include "afs/sysincludes.h"
5 #include "afsincludes.h"
6
7 #define MYBUNDLEID "org.openafs.filesystems.afs"
8 extern struct vfsops afs_vfsops;
9
10 #ifdef AFS_DARWIN80_ENV
11 static vfstable_t afs_vfstable;
12 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
13 extern struct vnodeopv_desc afs_dead_vnodeop_opv_desc;
14 static struct vnodeopv_desc *afs_vnodeop_opv_desc_list[2] =
15    { &afs_vnodeop_opv_desc, &afs_dead_vnodeop_opv_desc };
16
17 struct vfs_fsentry afs_vfsentry = {
18   &afs_vfsops,
19   2,
20   afs_vnodeop_opv_desc_list,
21   0,
22   "afs",
23   VFS_TBLNOTYPENUM|VFS_TBLTHREADSAFE|VFS_TBL64BITREADY,
24   NULL,
25   NULL,
26 };
27
28 #include <sys/conf.h>
29 #include <miscfs/devfs/devfs.h>
30 #define seltrue eno_select
31 struct cdevsw afs_cdev = NO_CDEVICE;
32 #undef seltrue
33 static int afs_cdev_major;
34 extern open_close_fcn_t afs_cdev_nop_openclose;
35 extern ioctl_fcn_t afs_cdev_ioctl;
36 static void *afs_cdev_devfs_handle;
37 #else
38 #include <sys/syscall.h>
39 struct vfsconf afs_vfsconf;
40 #endif
41 #include <mach/kmod.h>
42
43 extern struct mount *afs_globalVFS;
44 extern int Afs_xsetgroups();
45
46 extern int ioctl();
47 extern int setgroups();
48 extern int maxvfsconf;
49 kern_return_t
50 afs_modload(struct kmod_info *kmod_info, void *data)
51 {
52     int ret;
53 #ifdef AFS_DARWIN80_ENV
54     MUTEX_SETUP();
55     osi_Init();
56     afs_global_lock = lck_mtx_alloc_init(openafs_lck_grp, 0);
57
58     if (ret = vfs_fsadd(&afs_vfsentry, &afs_vfstable)) {
59         afs_warn("AFS: vfs_fsadd failed. aborting: %d\n", ret);
60         afs_vfstable = NULL;
61         goto fsadd_out;
62     }
63     afs_cdev.d_open = &afs_cdev_nop_openclose;
64     afs_cdev.d_close = &afs_cdev_nop_openclose;
65     afs_cdev.d_ioctl = &afs_cdev_ioctl;
66     afs_cdev_major = cdevsw_add(-1, &afs_cdev);
67     if (afs_cdev_major == -1) {
68         afs_warn("AFS: cdevsw_add failed. aborting\n");
69         goto cdevsw_out;
70     }
71     afs_cdev_devfs_handle = devfs_make_node(makedev(afs_cdev_major, 0),
72                                             DEVFS_CHAR, UID_ROOT, GID_WHEEL,
73                                             0666, "openafs_ioctl", 0);
74     if (!afs_cdev_devfs_handle) {
75         afs_warn("AFS: devfs_make_node failed. aborting\n");
76         cdevsw_remove(afs_cdev_major, &afs_cdev);
77     cdevsw_out:
78         vfs_fsremove(afs_vfstable);
79     fsadd_out:
80         MUTEX_FINISH();
81         lck_mtx_free(afs_global_lock, openafs_lck_grp);
82         return KERN_FAILURE;
83     }
84 #else
85     osi_Init();
86     memset(&afs_vfsconf, 0, sizeof(struct vfsconf));
87     strcpy(afs_vfsconf.vfc_name, "afs");
88     afs_vfsconf.vfc_vfsops = &afs_vfsops;
89     afs_vfsconf.vfc_typenum = maxvfsconf++;     /* oddly not VT_AFS */
90     afs_vfsconf.vfc_flags = MNT_NODEV;
91     if (vfsconf_add(&afs_vfsconf)) {
92         afs_warn("AFS: vfsconf_add failed. aborting\n");
93         return KERN_FAILURE;
94     }
95     if (sysent[AFS_SYSCALL].sy_call != nosys) {
96         afs_warn("AFS_SYSCALL in use. aborting\n");
97         return KERN_FAILURE;
98     }
99     sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
100     sysent[AFS_SYSCALL].sy_call = afs3_syscall;
101     sysent[AFS_SYSCALL].sy_narg = 5;
102     sysent[AFS_SYSCALL].sy_parallel = 0;
103 #ifdef KERNEL_FUNNEL
104     sysent[AFS_SYSCALL].sy_funnel = KERNEL_FUNNEL;
105 #endif
106 #endif
107     afs_warn("%s kext loaded; %u pages at 0x%lx (load tag %u).\n",
108            kmod_info->name, (unsigned)kmod_info->size / PAGE_SIZE,
109            (unsigned long)kmod_info->address, (unsigned)kmod_info->id);
110
111     return KERN_SUCCESS;
112 }
113
114 kern_return_t
115 afs_modunload(struct kmod_info * kmod_info, void *data)
116 {
117     if (afs_globalVFS)
118         return KERN_FAILURE;
119     if ((afs_initState != 0) || (afs_shuttingdown != AFS_RUNNING))
120         return KERN_FAILURE;
121 #ifdef AFS_DARWIN80_ENV
122     if (vfs_fsremove(afs_vfstable))
123         return KERN_FAILURE;
124     devfs_remove(afs_cdev_devfs_handle);
125     cdevsw_remove(afs_cdev_major, &afs_cdev);
126 #else
127     if (vfsconf_del("afs"))
128         return KERN_FAILURE;
129     /* give up syscall entries for ioctl & setgroups, which we've stolen */
130     sysent[SYS_setgroups].sy_call = setgroups;
131     /* give up the stolen syscall entry */
132     sysent[AFS_SYSCALL].sy_narg = 0;
133     sysent[AFS_SYSCALL].sy_call = nosys;
134 #endif
135 #ifdef AFS_DARWIN80_ENV
136     MUTEX_FINISH();
137     lck_mtx_free(afs_global_lock, openafs_lck_grp);
138 #endif
139     afs_warn("%s kext unloaded; (load tag %u).\n",
140            kmod_info->name, (unsigned)kmod_info->id);
141     return KERN_SUCCESS;
142 }
143
144 KMOD_EXPLICIT_DECL(MYBUNDLEID, VERSION, afs_modload,
145                    afs_modunload)