2 * OpenBSD specific assistance routines & VFS ops
3 * Original NetBSD version for Transarc afs by John Kohl <jtk@MIT.EDU>
4 * OpenBSD version by Jim Rees <rees@umich.edu>
11 the regents of the university of michigan
14 permission is granted to use, copy, create derivative works
15 and redistribute this software and such derivative works
16 for any purpose, so long as the name of the university of
17 michigan is not used in any advertising or publicity
18 pertaining to the use or distribution of this software
19 without specific, written prior authorization. if the
20 above copyright notice or any other identification of the
21 university of michigan is included in any copy of any
22 portion of this software, then the disclaimer below must
25 this software is provided as is, without representation
26 from the university of michigan as to its fitness for any
27 purpose, and without warranty by the university of
28 michigan of any kind, either express or implied, including
29 without limitation the implied warranties of
30 merchantability and fitness for a particular purpose. the
31 regents of the university of michigan shall not be liable
32 for any damages, including special, indirect, incidental, or
33 consequential damages, with respect to any claim arising
34 out of or in connection with the use of the software, even
35 if it has been or is hereafter advised of the possibility of
40 Copyright 1995 Massachusetts Institute of Technology. All Rights
43 You are hereby granted a worldwide, irrevocable, paid-up, right and
44 license to use, execute, display, modify, copy and distribute MIT's
45 Modifications, provided that (i) you abide by the terms and conditions
46 of your Transarc AFS License Agreement, and (ii) you do not use the name
47 of MIT in any advertising or publicity without the prior written consent
48 of MIT. MIT disclaims all liability for your use of MIT's
49 Modifications. MIT's Modifications are provided "AS IS" WITHOUT
50 WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO,
51 ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
56 * Some code cribbed from ffs_vfsops and other NetBSD sources, which
60 * Copyright (c) 1989, 1991, 1993, 1994
61 * The Regents of the University of California. All rights reserved.
63 * Redistribution and use in source and binary forms, with or without
64 * modification, are permitted provided that the following conditions
66 * 1. Redistributions of source code must retain the above copyright
67 * notice, this list of conditions and the following disclaimer.
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in the
70 * documentation and/or other materials provided with the distribution.
71 * 3. All advertising materials mentioning features or use of this software
72 * must display the following acknowledgement:
73 * This product includes software developed by the University of
74 * California, Berkeley and its contributors.
75 * 4. Neither the name of the University nor the names of its contributors
76 * may be used to endorse or promote products derived from this software
77 * without specific prior written permission.
79 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
80 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
81 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
82 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
83 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
84 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
85 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
86 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
87 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
88 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
93 #include <afsconfig.h>
94 #include "afs/param.h"
98 #include "afs/sysincludes.h" /* Standard vendor system headers */
99 #include "afs/afsincludes.h" /* Afs-based standard headers */
100 #include "afs/afs_stats.h" /* statistics */
102 #include <sys/conf.h>
103 #include <sys/exec.h>
105 #include <sys/namei.h>
106 #include <sys/syscall.h>
107 #include <sys/syscallargs.h>
109 #define NBSD_DONTFOLLOW_LINK 0
110 #define NBSD_FOLLOW_LINK 1
111 static int lkmid = -1;
112 static int afs_badcall(struct proc *p, void *xx, register_t *yy);
114 char afs_NetBSD_osname[] = "OpenBSD";
115 struct osi_vfs *afs_globalVFS;
116 struct vcache *afs_globalVp;
132 struct vfsops afs_vfsops = {
149 afs_nbsd_lookupname(char *fnamep,
152 struct vnode **dirvpp,
153 struct vnode **compvpp)
160 * Lookup pathname "fnamep", returning parent directory in
161 * *dirvpp (if non-null) and leaf in *compvpp. segflg says whether the
162 * pathname is user or system space.
165 niflag = (followlink == NBSD_FOLLOW_LINK) ? FOLLOW : NOFOLLOW;
167 niflag |= WANTPARENT; /* XXX LOCKPARENT? */
171 fnamep, osi_curproc());
172 if ((error = namei(&nd)))
182 afs_rdwr(struct vnode *vp, struct uio *uiop, enum uio_rw op,
183 int flags, struct AFS_UCRED *cred)
187 return VOP_READ(vp, uiop, flags, cred);
189 return VOP_WRITE(vp, uiop, flags, cred);
191 panic("afs_rdwr mode");
216 afs_fhtovp(mp, fhp, vpp)
235 afs_start(mp, flags, p)
240 return (0); /* nothing to do. ? */
244 afs_mount(mp, path, data, ndp, p)
245 register struct mount *mp;
248 struct nameidata *ndp;
251 /* ndp contains the mounted-from device. Just ignore it.
252 we also don't care about our proc struct. */
255 if (mp->mnt_flag & MNT_UPDATE)
259 /* Don't allow remounts */
264 AFS_STATCNT(afs_mount);
266 #ifdef AFS_DISCON_ENV
267 /* initialize the vcache entries before we start using them */
269 /* XXX find a better place for this if possible */
270 init_vcache_entries();
273 mp->osi_vfs_bsize = 8192;
274 mp->osi_vfs_fsid.val[0] = AFS_VFSMAGIC; /* magic */
275 mp->osi_vfs_fsid.val[1] = (int) AFS_VFSFSID;
279 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN-1, &size);
280 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
281 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
282 strcpy(mp->mnt_stat.f_mntfromname, "AFS");
283 /* null terminated string "AFS" will fit, just leave it be. */
284 strcpy(mp->mnt_stat.f_fstypename, MOUNT_AFS);
285 (void) afs_statfs(mp, &mp->mnt_stat);
291 afs_unmount(afsp, flags, p)
296 extern int sys_ioctl(), sys_setgroups();
298 AFS_STATCNT(afs_unmount);
299 #ifdef AFS_DISCON_ENV
302 if (!afs_globalVFS) {
303 printf("afs already unmounted\n");
307 AFS_RELE(AFSTOV(afs_globalVp));
310 vflush(afsp, NULLVP, 0); /* don't support forced */
311 afsp->mnt_data = NULL;
312 #ifdef AFS_GLOBAL_SUNLOCK
313 mutex_enter(&afs_global_lock);
316 afs_cold_shutdown = 1;
317 afs_shutdown(); /* XXX */
318 #ifdef AFS_GLOBAL_SUNLOCK
319 mutex_exit(&afs_global_lock);
322 /* give up syscall entries for ioctl & setgroups, which we've stolen */
323 sysent[SYS_ioctl].sy_call = sys_ioctl;
324 sysent[SYS_setgroups].sy_call = sys_setgroups;
326 /* give up the stolen syscall entry */
327 sysent[AFS_SYSCALL].sy_narg = 0;
328 sysent[AFS_SYSCALL].sy_argsize = 0;
329 sysent[AFS_SYSCALL].sy_call = afs_badcall;
330 printf("AFS unmounted--use `/sbin/modunload -i %d' to unload before restarting AFS\n", lkmid);
335 afs_badcall(struct proc *p, void *xx, register_t *yy)
341 afs_nbsd_getnewvnode(struct vcache *tvc)
343 while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) {
344 /* no vnodes available, force an alloc (limits be damned)! */
347 tvc->v->v_data = (void *)tvc;
351 afs_root(struct mount *mp,
354 struct vrequest treq;
358 AFS_STATCNT(afs_root);
360 #ifdef AFS_GLOBAL_SUNLOCK
361 mutex_enter(&afs_global_lock);
363 if (!(code = afs_InitReq(&treq, osi_curcred())) &&
364 !(code = afs_CheckInit())) {
365 tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
367 /* There is really no reason to over-hold this bugger--it's held
368 by the root filesystem reference. */
369 if (afs_globalVp != tvp) {
370 #ifdef AFS_DONT_OVERHOLD_GLOBALVP
372 AFS_RELE(AFSTOV(afs_globalVp));
375 AFS_HOLD(AFSTOV(afs_globalVp));
377 AFSTOV(tvp)->v_flag |= VROOT;
383 #ifdef AFS_GLOBAL_SUNLOCK
384 mutex_exit(&afs_global_lock);
388 vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curproc); /* return it locked */
393 afs_statfs(struct osi_vfs *afsp, struct statfs *abp)
395 AFS_STATCNT(afs_statfs);
396 #ifdef AFS_GLOBAL_SUNLOCK
397 mutex_enter(&afs_global_lock);
399 abp->f_bsize = afsp->osi_vfs_bsize;
400 /* 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)) */
401 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files = abp->f_ffree = 9000000; /* XXX */
402 abp->f_fsid.val[0] = AFS_VFSMAGIC; /* magic */
403 abp->f_fsid.val[1] = (int) AFS_VFSFSID;
404 #ifdef AFS_GLOBAL_SUNLOCK
405 mutex_exit(&afs_global_lock);
411 afs_sync(struct osi_vfs *afsp)
413 AFS_STATCNT(afs_sync);
414 #if defined(AFS_DISCON_ENV) && !defined(AFS_OBSD_ENV)
415 /* Can't do this in OpenBSD 2.7, it faults when called from apm_suspend() */
416 store_dirty_vcaches();
422 afs_nbsd_ref(struct vnode *vp)
424 if (vp->v_usecount == 0) {
425 vprint("holding unheld node", vp);
432 afs_nbsd_rele(struct vnode *vp)
434 if (vp->v_usecount <= 0) {
435 vprint("rele'ing unheld node", vp);
448 if (vp->v_usecount < 0) {
449 vprint("bad usecount", vp);
452 error = vget(vp, lfl, curproc);
454 insmntque(vp, afs_globalVFS); /* take off free list */
458 extern struct vfsops afs_vfsops;
459 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
461 static struct vfsconf afs_vfsconf = {
471 MOD_VFS("afs", 0, &afs_vfsconf);
473 static char afsgenmem[] = "afsgenmem";
474 static char afsfidmem[] = "afsfidmem";
475 static char afsbhdrmem[] = "afsbhdrmem";
476 static char afsbfrmem[] = "afsbfrmem";
481 extern int afs3_syscall(), afs_xioctl(), Afs_xsetgroups(), afs_xflock();
483 sysent[AFS_SYSCALL].sy_call = afs3_syscall;
484 sysent[AFS_SYSCALL].sy_narg = 6;
485 sysent[AFS_SYSCALL].sy_argsize = 6 * sizeof(long);
486 sysent[54].sy_call = afs_xioctl;
487 sysent[80].sy_call = Afs_xsetgroups;
493 afs_vfs_load(struct lkm_table *lkmtp,
496 extern char *memname[];
498 vfs_opv_init_explicit(&afs_vnodeop_opv_desc);
499 vfs_opv_init_default(&afs_vnodeop_opv_desc);
500 if (memname[M_AFSGENERIC] == NULL)
501 memname[M_AFSGENERIC] = afsgenmem;
502 if (memname[M_AFSFID] == NULL)
503 memname[M_AFSFID] = afsfidmem;
504 if (memname[M_AFSBUFHDR] == NULL)
505 memname[M_AFSBUFHDR] = afsbhdrmem;
506 if (memname[M_AFSBUFFER] == NULL)
507 memname[M_AFSBUFFER] = afsbfrmem;
509 printf("OpenAFS ($Revision$) lkm loaded\n");
514 afs_vfs_unload(struct lkm_table *lktmp,
517 extern char *memname[];
518 extern int sys_lkmnosys();
522 if (sysent[SYS_ioctl].sy_call != sys_ioctl)
525 if (memname[M_AFSGENERIC] == afsgenmem)
526 memname[M_AFSGENERIC] = NULL;
527 if (memname[M_AFSFID] == afsfidmem)
528 memname[M_AFSFID] = NULL;
529 if (memname[M_AFSBUFHDR] == afsbhdrmem)
530 memname[M_AFSBUFHDR] = NULL;
531 if (memname[M_AFSBUFFER] == afsbfrmem)
532 memname[M_AFSBUFFER] = NULL;
534 sysent[AFS_SYSCALL].sy_call = sys_lkmnosys;
535 printf("OpenAFS unloaded\n");
542 afsmodload(struct lkm_table *lkmtp,
546 extern int sys_lkmnosys();
548 if (cmd == LKM_E_LOAD) {
549 if (strcmp(ostype,afs_NetBSD_osname)) {
550 printf("This is %s version %s\n", ostype, osrelease);
551 printf("This version of AFS is only for %s\n",
553 /* return EPROGMISMATCH;*/
555 if (sysent[AFS_SYSCALL].sy_call != sys_lkmnosys) {
556 printf("AFS must be loaded with syscall %d assigned to sys_lkmnosys\nIs AFS already loaded?\n",
561 DISPATCH(lkmtp,cmd,ver,afs_vfs_load,afs_vfs_unload,lkm_nofunc);