2 Copyright 1995 Massachusetts Institute of Technology. All Rights
5 You are hereby granted a worldwide, irrevocable, paid-up, right and
6 license to use, execute, display, modify, copy and distribute MIT's
7 Modifications, provided that (i) you abide by the terms and conditions
8 of your Transarc AFS License Agreement, and (ii) you do not use the name
9 of MIT in any advertising or publicity without the prior written consent
10 of MIT. MIT disclaims all liability for your use of MIT's
11 Modifications. MIT's Modifications are provided "AS IS" WITHOUT
12 WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO,
13 ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
18 * OpenBSD specific assistance routines & VFS ops
19 * Original NetBSD version for Transarc afs by John Kohl <jtk@MIT.EDU>
20 * OpenBSD version by Jim Rees <rees@umich.edu>
26 * Some code cribbed from ffs_vfsops and other NetBSD sources, which
30 * Copyright (c) 1989, 1991, 1993, 1994
31 * The Regents of the University of California. All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by the University of
44 * California, Berkeley and its contributors.
45 * 4. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 #include <afsconfig.h>
64 #include "afs/param.h"
68 #include "afs/sysincludes.h" /* Standard vendor system headers */
69 #include "afs/afsincludes.h" /* Afs-based standard headers */
70 #include "afs/afs_stats.h" /* statistics */
75 #include <sys/namei.h>
76 #include <sys/syscall.h>
77 #include <sys/syscallargs.h>
79 #define NBSD_DONTFOLLOW_LINK 0
80 #define NBSD_FOLLOW_LINK 1
81 static int lkmid = -1;
82 static int afs_badcall(struct proc *p, void *xx, register_t *yy);
84 char afs_NetBSD_osname[] = "OpenBSD";
85 struct osi_vfs *afs_globalVFS;
86 struct vcache *afs_globalVp;
102 struct vfsops afs_vfsops = {
119 afs_nbsd_lookupname(char *fnamep,
122 struct vnode **dirvpp,
123 struct vnode **compvpp)
130 * Lookup pathname "fnamep", returning parent directory in
131 * *dirvpp (if non-null) and leaf in *compvpp. segflg says whether the
132 * pathname is user or system space.
135 niflag = (followlink == NBSD_FOLLOW_LINK) ? FOLLOW : NOFOLLOW;
137 niflag |= WANTPARENT; /* XXX LOCKPARENT? */
141 fnamep, osi_curproc());
142 if ((error = namei(&nd)))
152 afs_rdwr(struct vnode *vp, struct uio *uiop, enum uio_rw op,
153 int flags, struct AFS_UCRED *cred)
157 return VOP_READ(vp, uiop, flags, cred);
159 return VOP_WRITE(vp, uiop, flags, cred);
161 panic("afs_rdwr mode");
186 afs_fhtovp(mp, fhp, vpp)
205 afs_start(mp, flags, p)
210 return (0); /* nothing to do. ? */
214 afs_mount(mp, path, data, ndp, p)
215 register struct mount *mp;
218 struct nameidata *ndp;
221 /* ndp contains the mounted-from device. Just ignore it.
222 we also don't care about our proc struct. */
225 if (mp->mnt_flag & MNT_UPDATE)
229 /* Don't allow remounts */
234 AFS_STATCNT(afs_mount);
236 #ifdef AFS_DISCON_ENV
237 /* initialize the vcache entries before we start using them */
239 /* XXX find a better place for this if possible */
240 init_vcache_entries();
243 mp->osi_vfs_bsize = 8192;
244 mp->osi_vfs_fsid.val[0] = AFS_VFSMAGIC; /* magic */
245 mp->osi_vfs_fsid.val[1] = (int) AFS_VFSFSID;
249 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN-1, &size);
250 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
251 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
252 strcpy(mp->mnt_stat.f_mntfromname, "AFS");
253 /* null terminated string "AFS" will fit, just leave it be. */
254 strcpy(mp->mnt_stat.f_fstypename, MOUNT_AFS);
255 (void) afs_statfs(mp, &mp->mnt_stat);
261 afs_unmount(afsp, flags, p)
266 extern int sys_ioctl(), sys_setgroups();
268 AFS_STATCNT(afs_unmount);
269 #ifdef AFS_DISCON_ENV
272 if (!afs_globalVFS) {
273 printf("afs already unmounted\n");
277 AFS_RELE(AFSTOV(afs_globalVp));
280 vflush(afsp, NULLVP, 0); /* don't support forced */
281 afsp->mnt_data = NULL;
282 #ifdef AFS_GLOBAL_SUNLOCK
283 mutex_enter(&afs_global_lock);
286 afs_cold_shutdown = 1;
287 afs_shutdown(); /* XXX */
288 #ifdef AFS_GLOBAL_SUNLOCK
289 mutex_exit(&afs_global_lock);
292 /* give up syscall entries for ioctl & setgroups, which we've stolen */
293 sysent[SYS_ioctl].sy_call = sys_ioctl;
294 sysent[SYS_setgroups].sy_call = sys_setgroups;
296 /* give up the stolen syscall entry */
297 sysent[AFS_SYSCALL].sy_narg = 0;
298 sysent[AFS_SYSCALL].sy_argsize = 0;
299 sysent[AFS_SYSCALL].sy_call = afs_badcall;
300 printf("AFS unmounted--use `/sbin/modunload -i %d' to unload before restarting AFS\n", lkmid);
305 afs_badcall(struct proc *p, void *xx, register_t *yy)
311 afs_nbsd_getnewvnode(struct vcache *tvc)
313 while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) {
314 /* no vnodes available, force an alloc (limits be damned)! */
317 tvc->v->v_data = (void *)tvc;
321 afs_root(struct mount *mp,
324 struct vrequest treq;
328 AFS_STATCNT(afs_root);
330 #ifdef AFS_GLOBAL_SUNLOCK
331 mutex_enter(&afs_global_lock);
333 if (!(code = afs_InitReq(&treq, osi_curcred())) &&
334 !(code = afs_CheckInit())) {
335 tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
337 printf("tvp %x %d\n", tvp, AFSTOV(tvp)->v_usecount);
338 /* There is really no reason to over-hold this bugger--it's held
339 by the root filesystem reference. */
340 if (afs_globalVp != tvp) {
342 printf("afs_globalVp %x %d\n", afs_globalVp, AFSTOV(afs_globalVp)->v_usecount);
343 /* AFS_RELE(AFSTOV(afs_globalVp));*/
345 AFS_HOLD(AFSTOV(afs_globalVp));
347 AFSTOV(tvp)->v_flag |= VROOT;
353 #ifdef AFS_GLOBAL_SUNLOCK
354 mutex_exit(&afs_global_lock);
358 vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curproc); /* return it locked */
363 afs_statfs(struct osi_vfs *afsp, struct statfs *abp)
365 AFS_STATCNT(afs_statfs);
366 #ifdef AFS_GLOBAL_SUNLOCK
367 mutex_enter(&afs_global_lock);
369 abp->f_bsize = afsp->osi_vfs_bsize;
370 /* Fake a high number below to satisfy programs that use the ustat (for AIX), or statfs (for the rest) call to make sure that there's enough space in the device partition before storing something there (like ed(1)) */
371 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files = abp->f_ffree = 9000000; /* XXX */
372 abp->f_fsid.val[0] = AFS_VFSMAGIC; /* magic */
373 abp->f_fsid.val[1] = (int) AFS_VFSFSID;
374 #ifdef AFS_GLOBAL_SUNLOCK
375 mutex_exit(&afs_global_lock);
381 afs_sync(struct osi_vfs *afsp)
383 AFS_STATCNT(afs_sync);
384 #if defined(AFS_DISCON_ENV) && !defined(AFS_OBSD_ENV)
385 /* Can't do this in OpenBSD 2.7, it faults when called from apm_suspend() */
386 store_dirty_vcaches();
392 afs_nbsd_ref(struct vnode *vp)
394 if (vp->v_usecount == 0) {
395 vprint("holding unheld node", vp);
402 afs_nbsd_rele(struct vnode *vp)
404 if (vp->v_usecount <= 0) {
405 vprint("rele'ing unheld node", vp);
418 if (vp->v_usecount < 0) {
419 vprint("bad usecount", vp);
422 error = vget(vp, lfl, curproc);
424 insmntque(vp, afs_globalVFS); /* take off free list */
428 extern struct vfsops afs_vfsops;
429 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
431 static struct vfsconf afs_vfsconf = {
441 MOD_VFS("afs", 0, &afs_vfsconf);
443 static char afsgenmem[] = "afsgenmem";
444 static char afsfidmem[] = "afsfidmem";
445 static char afsbhdrmem[] = "afsbhdrmem";
446 static char afsbfrmem[] = "afsbfrmem";
451 extern int afs3_syscall(), afs_xioctl(), Afs_xsetgroups(), afs_xflock();
453 sysent[AFS_SYSCALL].sy_call = afs3_syscall;
454 sysent[AFS_SYSCALL].sy_narg = 6;
455 sysent[AFS_SYSCALL].sy_argsize = 6 * sizeof(long);
456 sysent[54].sy_call = afs_xioctl;
457 sysent[80].sy_call = Afs_xsetgroups;
463 afs_vfs_load(struct lkm_table *lkmtp,
466 extern char *memname[];
468 vfs_opv_init_explicit(&afs_vnodeop_opv_desc);
469 vfs_opv_init_default(&afs_vnodeop_opv_desc);
470 if (memname[M_AFSGENERIC] == NULL)
471 memname[M_AFSGENERIC] = afsgenmem;
472 if (memname[M_AFSFID] == NULL)
473 memname[M_AFSFID] = afsfidmem;
474 if (memname[M_AFSBUFHDR] == NULL)
475 memname[M_AFSBUFHDR] = afsbhdrmem;
476 if (memname[M_AFSBUFFER] == NULL)
477 memname[M_AFSBUFFER] = afsbfrmem;
479 printf("OpenAFS ($Revision$) lkm loaded\n");
484 afs_vfs_unload(struct lkm_table *lktmp,
487 extern char *memname[];
488 extern int sys_lkmnosys();
492 if (sysent[SYS_ioctl].sy_call != sys_ioctl)
495 if (memname[M_AFSGENERIC] == afsgenmem)
496 memname[M_AFSGENERIC] = NULL;
497 if (memname[M_AFSFID] == afsfidmem)
498 memname[M_AFSFID] = NULL;
499 if (memname[M_AFSBUFHDR] == afsbhdrmem)
500 memname[M_AFSBUFHDR] = NULL;
501 if (memname[M_AFSBUFFER] == afsbfrmem)
502 memname[M_AFSBUFFER] = NULL;
504 sysent[AFS_SYSCALL].sy_call = sys_lkmnosys;
505 printf("OpenAFS unloaded\n");
512 afsmodload(struct lkm_table *lkmtp,
516 extern int sys_lkmnosys();
518 if (cmd == LKM_E_LOAD) {
519 if (strcmp(ostype,afs_NetBSD_osname)) {
520 printf("This is %s version %s\n", ostype, osrelease);
521 printf("This version of AFS is only for %s\n",
523 /* return EPROGMISMATCH;*/
525 if (sysent[AFS_SYSCALL].sy_call != sys_lkmnosys) {
526 printf("AFS must be loaded with syscall %d assigned to sys_lkmnosys\nIs AFS already loaded?\n",
531 DISPATCH(lkmtp,cmd,ver,afs_vfs_load,afs_vfs_unload,lkm_nofunc);