Commit | Line | Data |
---|---|---|
805e021f CE |
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, PACKAGE_VERSION, afs_modload, | |
145 | afs_modunload) |