Commit | Line | Data |
---|---|---|
805e021f CE |
1 | /* |
2 | * Copyright 2000, International Business Machines Corporation and others. | |
3 | * All Rights Reserved. | |
4 | * | |
5 | * This software has been released under the terms of the IBM Public | |
6 | * License. For details, see the LICENSE file in the top-level source | |
7 | * directory or online at http://www.openafs.org/dl/license10.html | |
8 | */ | |
9 | ||
10 | /* | |
11 | * osi_vfsops.c for HPUX | |
12 | */ | |
13 | #include <afsconfig.h> | |
14 | #include "afs/param.h" | |
15 | ||
16 | ||
17 | #include "afs/sysincludes.h" /* Standard vendor system headers */ | |
18 | #include "afsincludes.h" /* Afs-based standard headers */ | |
19 | #include "afs/afs_stats.h" /* statistics stuff */ | |
20 | #include <sys/scall_kernprivate.h> | |
21 | ||
22 | #if defined(AFS_HPUX1123_ENV) | |
23 | #include <sys/moddefs.h> | |
24 | #endif /* AFS_HPUX1123_ENV */ | |
25 | ||
26 | #if defined(AFS_HPUX1123_ENV) | |
27 | /* defind DLKM tables so we can load dynamicly */ | |
28 | /* we still need an afs_unload to unload */ | |
29 | /* Note: There is to be a dependency on the | |
30 | * the name of the struct <name>_wrapper, and the | |
31 | * name of the dynamicly loaded file <name> | |
32 | * We will define -DAFS_WRAPPER=<name>_wrapper | |
33 | * and -DAFS_CONF_DATA=<name>_conf_data and pass into | |
34 | * this routine | |
35 | */ | |
36 | ||
37 | extern struct mod_operations mod_misc_ops; | |
38 | extern struct mod_conf_data AFS_CONF_DATA; | |
39 | ||
40 | static int afs_load(void *arg); | |
41 | /* static int afs_unload(void *arg); */ | |
42 | ||
43 | struct mod_type_data afs_mod_link = { | |
44 | "AFS kernel module", | |
45 | NULL | |
46 | }; | |
47 | ||
48 | struct modlink afs_modlink[] = { | |
49 | {&mod_misc_ops, &afs_mod_link}, | |
50 | { NULL, NULL } | |
51 | }; | |
52 | ||
53 | struct modwrapper AFS_WRAPPER = { | |
54 | MODREV, | |
55 | afs_load, | |
56 | NULL, /* should be afs_unload if we had one */ | |
57 | NULL, | |
58 | &AFS_CONF_DATA, | |
59 | afs_modlink | |
60 | }; | |
61 | ||
62 | #endif /* AFS_HPUX1123_ENV */ | |
63 | ||
64 | static char afs_mountpath[512]; | |
65 | struct vfs *afs_globalVFS = 0; | |
66 | struct vcache *afs_globalVp = 0; | |
67 | ||
68 | int | |
69 | afs_mount(struct vfs *afsp, char *path, smountargs_t * data) | |
70 | { | |
71 | AFS_GLOCK(); | |
72 | AFS_STATCNT(afs_mount); | |
73 | ||
74 | if (afs_globalVFS) { /* Don't allow remounts. */ | |
75 | AFS_GUNLOCK(); | |
76 | return (setuerror(EBUSY)); | |
77 | } | |
78 | ||
79 | afs_globalVFS = afsp; | |
80 | afsp->vfs_bsize = 8192; | |
81 | afsp->vfs_fsid[0] = AFS_VFSMAGIC; /* magic */ | |
82 | afsp->vfs_fsid[1] = AFS_VFSFSID; | |
83 | strcpy(afsp->vfs_name, "AFS"); | |
84 | afsp->vfs_name[3] = '\0'; | |
85 | ||
86 | strncpy(afs_mountpath, path, sizeof(afs_mountpath)); | |
87 | afs_mountpath[sizeof afs_mountpath - 1] = '\0'; | |
88 | ||
89 | #ifndef AFS_NONFSTRANS | |
90 | /* Set up the xlator in case it wasn't done elsewhere */ | |
91 | afs_xlatorinit_v2(); | |
92 | #endif | |
93 | ||
94 | AFS_GUNLOCK(); | |
95 | return 0; | |
96 | } | |
97 | ||
98 | ||
99 | int | |
100 | afs_unmount(struct vfs *afsp) | |
101 | { | |
102 | AFS_GLOCK(); | |
103 | AFS_STATCNT(afs_unmount); | |
104 | ||
105 | afs_globalVFS = 0; | |
106 | afs_shutdown(); | |
107 | ||
108 | AFS_GUNLOCK(); | |
109 | return 0; | |
110 | } | |
111 | ||
112 | int | |
113 | afs_root(struct vfs *afsp, struct vnode **avpp, char *unused1) | |
114 | { | |
115 | int code = 0; | |
116 | struct vrequest treq; | |
117 | struct vcache *tvp = 0; | |
118 | AFS_GLOCK(); | |
119 | AFS_STATCNT(afs_root); | |
120 | ||
121 | if (afs_globalVp && (afs_globalVp->f.states & CStatd)) { | |
122 | tvp = afs_globalVp; | |
123 | } else { | |
124 | if (afs_globalVp) { | |
125 | afs_PutVCache(afs_globalVp); | |
126 | afs_globalVp = NULL; | |
127 | } | |
128 | ||
129 | if (!(code = afs_InitReq(&treq, p_cred(u.u_procp))) | |
130 | && !(code = afs_CheckInit())) { | |
131 | tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL); | |
132 | /* we really want this to stay around */ | |
133 | if (tvp) { | |
134 | afs_globalVp = tvp; | |
135 | } else | |
136 | code = EIO; | |
137 | } | |
138 | } | |
139 | if (tvp) { | |
140 | VN_HOLD(AFSTOV(tvp)); | |
141 | SET_V_FLAG(AFSTOV(tvp), VROOT); | |
142 | ||
143 | afs_globalVFS = afsp; | |
144 | *avpp = AFSTOV(tvp); | |
145 | } | |
146 | ||
147 | afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp, | |
148 | ICL_TYPE_INT32, code); | |
149 | ||
150 | AFS_GUNLOCK(); | |
151 | return code; | |
152 | } | |
153 | ||
154 | int | |
155 | afs_statfs(struct vfs *afsp, struct k_statvfs *abp) | |
156 | { | |
157 | AFS_GLOCK(); | |
158 | AFS_STATCNT(afs_statfs); | |
159 | ||
160 | abp->f_type = 0; | |
161 | abp->f_frsize = 1024; | |
162 | abp->f_bsize = afsp->vfs_bsize; | |
163 | /* Fake a high number below to satisfy programs that use the statfs | |
164 | * call to make sure that there's enough space in the device partition | |
165 | * before storing something there. | |
166 | */ | |
167 | abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files = | |
168 | abp->f_ffree = abp->f_favail = AFS_VFS_FAKEFREE; | |
169 | abp->f_fsid = (AFS_VFSMAGIC << 16) || AFS_VFSFSID; | |
170 | ||
171 | AFS_GUNLOCK(); | |
172 | return 0; | |
173 | } | |
174 | ||
175 | int | |
176 | afs_sync(struct vfs *unused1, int unused2) | |
177 | { | |
178 | AFS_STATCNT(afs_sync); | |
179 | return 0; | |
180 | } | |
181 | ||
182 | int | |
183 | afs_vget(struct vfs *afsp, struct vnode **avcp, struct fid *fidp) | |
184 | { | |
185 | int code; | |
186 | struct vrequest treq; | |
187 | AFS_GLOCK(); | |
188 | AFS_STATCNT(afs_vget); | |
189 | ||
190 | *avcp = NULL; | |
191 | ||
192 | if ((code = afs_InitReq(&treq, p_cred(u.u_procp))) == 0) { | |
193 | code = afs_osi_vget((struct vcache **)avcp, fidp, &treq); | |
194 | } | |
195 | ||
196 | afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp, | |
197 | ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, fidp); | |
198 | code = afs_CheckCode(code, &treq, 42); | |
199 | ||
200 | AFS_GUNLOCK(); | |
201 | return code; | |
202 | } | |
203 | ||
204 | int | |
205 | afs_getmount(struct vfs *vfsp, char *fsmntdir, struct mount_data *mdp, | |
206 | char *unused1) | |
207 | { | |
208 | int l; | |
209 | ||
210 | mdp->md_msite = 0; | |
211 | mdp->md_dev = 0; | |
212 | mdp->md_rdev = 0; | |
213 | return (copyoutstr | |
214 | (afs_mountpath, fsmntdir, strlen(afs_mountpath) + 1, &l)); | |
215 | } | |
216 | ||
217 | ||
218 | struct vfsops Afs_vfsops = { | |
219 | afs_mount, | |
220 | afs_unmount, | |
221 | afs_root, | |
222 | afs_statfs, | |
223 | afs_sync, | |
224 | afs_vget, | |
225 | afs_getmount, | |
226 | (vfs_freeze_t *) 0, /* vfs_freeze */ | |
227 | (vfs_thaw_t *) 0, /* vfs_thaw */ | |
228 | (vfs_quota_t *) 0, /* vfs_quota */ | |
229 | (vfs_mountroot_t *) 0, /* vfs_mountroot. Note: afs_mountroot_nullop in this | |
230 | * position panicked HP 11.00+ | |
231 | */ | |
232 | (vfs_size_t *) 0 /* vfs_size */ | |
233 | }; | |
234 | ||
235 | static int afs_Starting = 0; | |
236 | ||
237 | #pragma align 64 | |
238 | #if !defined(AFS_HPUX110_ENV) | |
239 | sema_t afs_global_sema = { | |
240 | NULL, 0, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, /* sa_type */ | |
241 | 0, 0, 0, 0, 0, 0, 0, NULL, /* sa_link */ | |
242 | NULL, NULL | |
243 | #ifdef SEMA_COUNTING | |
244 | , 0, 0, 0, NULL | |
245 | #endif | |
246 | }; | |
247 | #else | |
248 | b_sema_t afs_global_sema = { 0 }; | |
249 | #endif | |
250 | ||
251 | void | |
252 | osi_InitGlock() | |
253 | { | |
254 | ulong_t context; | |
255 | ||
256 | SPINLOCK_USAV(sched_lock, context); | |
257 | if (!afs_Starting) { | |
258 | afs_Starting = 1; | |
259 | SPINUNLOCK_USAV(sched_lock, context); | |
260 | #if defined(AFS_HPUX110_ENV) | |
261 | b_initsema(&afs_global_sema, 1, NFS_LOCK_ORDER2, "AFS GLOCK"); | |
262 | /* afsHash(64); *//* 64 buckets */ | |
263 | #else | |
264 | initsema(&afs_global_sema, 1, FILESYS_SEMA_PRI, FILESYS_SEMA_ORDER); | |
265 | afsHash(64); /* 64 buckets */ | |
266 | #endif | |
267 | } else { | |
268 | SPINUNLOCK_USAV(sched_lock, context); | |
269 | } | |
270 | if (!afs_Starting) { | |
271 | osi_Panic("osi_Init lost initialization race"); | |
272 | } | |
273 | } | |
274 | ||
275 | #if defined(AFS_HPUX1123_ENV) | |
276 | /* DLKM routine called when loaded */ | |
277 | static int | |
278 | afs_load(void *arg) | |
279 | { | |
280 | afsc_link(); | |
281 | return 0; | |
282 | } | |
283 | #endif /* AFS_HPUX1123_ENV */ | |
284 | ||
285 | /* | |
286 | * afsc_link - Initialize VFS | |
287 | */ | |
288 | int afs_vfs_slot = -1; | |
289 | ||
290 | ||
291 | afsc_link() | |
292 | { | |
293 | extern int Afs_syscall(), afs_xioctl(), Afs_xsetgroups(); | |
294 | ||
295 | /* For now nothing special is required during AFS initialization. */ | |
296 | AFS_STATCNT(afsc_link); | |
297 | osi_Init(); | |
298 | if ((afs_vfs_slot = add_vfs_type("afs", &Afs_vfsops)) < 0) | |
299 | return; | |
300 | sysent_assign_function(AFS_SYSCALL, 7, (void (*)())Afs_syscall, | |
301 | "Afs_syscall"); | |
302 | sysent_define_arg(AFS_SYSCALL, 0, longArg); | |
303 | sysent_define_arg(AFS_SYSCALL, 1, longArg); | |
304 | sysent_define_arg(AFS_SYSCALL, 2, longArg); | |
305 | sysent_define_arg(AFS_SYSCALL, 3, longArg); | |
306 | sysent_define_arg(AFS_SYSCALL, 4, longArg); | |
307 | sysent_define_arg(AFS_SYSCALL, 5, longArg); | |
308 | sysent_define_arg(AFS_SYSCALL, 6, longArg); | |
309 | sysent_returns_long(AFS_SYSCALL); | |
310 | ||
311 | sysent_delete(80); | |
312 | sysent_assign_function(80, 2, (void (*)())Afs_xsetgroups, "setgroups"); | |
313 | sysent_define_arg(80, 0, longArg); | |
314 | sysent_define_arg(80, 1, longArg); | |
315 | sysent_returns_long(80); | |
316 | return 0; | |
317 | } |