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 /* from /usr/src/sys/kern/vfs_subr.c */
110 extern void insmntque(struct vnode *, struct mount *);
112 extern int sys_lkmnosys(), afs3_syscall(), afs_xioctl(), Afs_xsetgroups();
114 static int lkmid = -1;
115 static int afs_badcall(struct proc *p, void *xx, register_t *yy);
116 static struct sysent old_sysent;
118 char afs_NetBSD_osname[] = "OpenBSD";
119 struct osi_vfs *afs_globalVFS;
120 struct vcache *afs_globalVp;
136 struct vfsops afs_vfsops = {
153 afs_nbsd_lookupname(char *fnamep,
156 struct vnode **dirvpp,
157 struct vnode **compvpp)
164 * Lookup pathname "fnamep", returning parent directory in
165 * *dirvpp (if non-null) and leaf in *compvpp. segflg says whether the
166 * pathname is user or system space.
169 niflag = followlink ? FOLLOW : NOFOLLOW;
171 niflag |= WANTPARENT; /* XXX LOCKPARENT? */
175 fnamep, osi_curproc());
176 if ((error = namei(&nd)))
203 afs_fhtovp(mp, fhp, vpp)
222 afs_start(mp, flags, p)
227 return (0); /* nothing to do. ? */
231 afs_mount(mp, path, data, ndp, p)
232 register struct mount *mp;
235 struct nameidata *ndp;
238 /* ndp contains the mounted-from device. Just ignore it.
239 we also don't care about our proc struct. */
242 if (mp->mnt_flag & MNT_UPDATE)
246 /* Don't allow remounts */
250 AFS_STATCNT(afs_mount);
252 #ifdef AFS_DISCON_ENV
253 /* initialize the vcache entries before we start using them */
255 /* XXX find a better place for this if possible */
256 init_vcache_entries();
259 mp->osi_vfs_bsize = 8192;
260 mp->osi_vfs_fsid.val[0] = AFS_VFSMAGIC; /* magic */
261 mp->osi_vfs_fsid.val[1] = (int) AFS_VFSFSID;
263 (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN-1, &size);
264 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
265 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
266 strcpy(mp->mnt_stat.f_mntfromname, "AFS");
267 /* null terminated string "AFS" will fit, just leave it be. */
268 strcpy(mp->mnt_stat.f_fstypename, MOUNT_AFS);
269 (void) afs_statfs(mp, &mp->mnt_stat);
275 afs_unmount(afsp, flags, p)
280 extern int sys_ioctl(), sys_setgroups();
282 AFS_STATCNT(afs_unmount);
283 #ifdef AFS_DISCON_ENV
286 if (!afs_globalVFS) {
287 printf("afs already unmounted\n");
291 AFS_RELE(AFSTOV(afs_globalVp));
294 vflush(afsp, NULLVP, 0); /* don't support forced */
295 afsp->mnt_data = NULL;
298 afs_cold_shutdown = 1;
299 afs_shutdown(); /* XXX */
302 /* give up syscall entries for ioctl & setgroups, which we've stolen */
303 sysent[SYS_ioctl].sy_call = sys_ioctl;
304 sysent[SYS_setgroups].sy_call = sys_setgroups;
306 /* give up the stolen syscall entry */
307 sysent[AFS_SYSCALL].sy_narg = 0;
308 sysent[AFS_SYSCALL].sy_argsize = 0;
309 sysent[AFS_SYSCALL].sy_call = afs_badcall;
310 printf("AFS unmounted--use `/sbin/modunload -i %d' to unload before restarting AFS\n", lkmid);
315 afs_badcall(struct proc *p, void *xx, register_t *yy)
321 afs_nbsd_getnewvnode(struct vcache *tvc)
323 while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) {
324 /* no vnodes available, force an alloc (limits be damned)! */
327 tvc->v->v_data = (void *)tvc;
331 afs_root(struct mount *mp,
334 struct vrequest treq;
338 AFS_STATCNT(afs_root);
341 if (!(code = afs_InitReq(&treq, osi_curcred())) &&
342 !(code = afs_CheckInit())) {
343 tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
345 /* There is really no reason to over-hold this bugger--it's held
346 by the root filesystem reference. */
347 if (afs_globalVp != tvp) {
348 #ifdef AFS_DONT_OVERHOLD_GLOBALVP
350 AFS_RELE(AFSTOV(afs_globalVp));
353 AFS_HOLD(AFSTOV(afs_globalVp));
355 AFSTOV(tvp)->v_flag |= VROOT;
364 vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curproc); /* return it locked */
369 afs_statfs(struct osi_vfs *afsp, struct statfs *abp)
371 AFS_STATCNT(afs_statfs);
372 abp->f_bsize = afsp->osi_vfs_bsize;
375 * Fake a high number below to satisfy programs that use the ustat (for
376 * * AIX), or statfs (for the rest) call to make sure that there's
377 * enough * space in the device partition before storing something there
380 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files = abp->f_ffree = 9000000;
381 abp->f_fsid.val[0] = AFS_VFSMAGIC; /* magic */
382 abp->f_fsid.val[1] = (int) AFS_VFSFSID;
387 afs_sync(struct osi_vfs *afsp)
389 AFS_STATCNT(afs_sync);
390 #if defined(AFS_DISCON_ENV) && !defined(AFS_OBSD_ENV)
391 /* Can't do this in OpenBSD 2.7, it faults when called from apm_suspend() */
392 store_dirty_vcaches();
398 afs_nbsd_ref(struct vnode *vp)
400 if (vp->v_usecount == 0) {
401 vprint("holding unheld node", vp);
408 afs_nbsd_rele(struct vnode *vp)
410 if (vp->v_usecount <= 0) {
411 vprint("rele'ing unheld node", vp);
424 if (vp->v_usecount < 0) {
425 vprint("bad usecount", vp);
428 error = vget(vp, lfl, curproc);
430 insmntque(vp, afs_globalVFS); /* take off free list */
434 extern struct vfsops afs_vfsops;
435 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
437 static struct vfsconf afs_vfsconf = {
447 MOD_VFS("afs", 0, &afs_vfsconf);
449 static char afsgenmem[] = "afsgenmem";
450 static char afsfidmem[] = "afsfidmem";
451 static char afsbhdrmem[] = "afsbhdrmem";
452 static char afsbfrmem[] = "afsbfrmem";
457 old_sysent = sysent[AFS_SYSCALL];
459 sysent[AFS_SYSCALL].sy_call = afs3_syscall;
460 sysent[AFS_SYSCALL].sy_narg = 6;
461 sysent[AFS_SYSCALL].sy_argsize = 6 * sizeof(long);
462 sysent[54].sy_call = afs_xioctl;
463 sysent[80].sy_call = Afs_xsetgroups;
469 afs_vfs_load(struct lkm_table *lkmtp,
472 extern char *memname[];
474 vfs_opv_init_explicit(&afs_vnodeop_opv_desc);
475 vfs_opv_init_default(&afs_vnodeop_opv_desc);
476 if (memname[M_AFSGENERIC] == NULL)
477 memname[M_AFSGENERIC] = afsgenmem;
478 if (memname[M_AFSFID] == NULL)
479 memname[M_AFSFID] = afsfidmem;
480 if (memname[M_AFSBUFHDR] == NULL)
481 memname[M_AFSBUFHDR] = afsbhdrmem;
482 if (memname[M_AFSBUFFER] == NULL)
483 memname[M_AFSBUFFER] = afsbfrmem;
485 printf("OpenAFS ($Revision$) lkm loaded\n");
490 afs_vfs_unload(struct lkm_table *lktmp, int cmd)
492 extern char *memname[];
496 if (sysent[SYS_ioctl].sy_call != sys_ioctl)
499 if (memname[M_AFSGENERIC] == afsgenmem)
500 memname[M_AFSGENERIC] = NULL;
501 if (memname[M_AFSFID] == afsfidmem)
502 memname[M_AFSFID] = NULL;
503 if (memname[M_AFSBUFHDR] == afsbhdrmem)
504 memname[M_AFSBUFHDR] = NULL;
505 if (memname[M_AFSBUFFER] == afsbfrmem)
506 memname[M_AFSBUFFER] = NULL;
508 sysent[AFS_SYSCALL] = old_sysent;
509 printf("OpenAFS unloaded\n");
514 afsmodload(struct lkm_table *lkmtp, int cmd, int ver)
516 if (cmd == LKM_E_LOAD) {
517 if (strcmp(ostype, afs_NetBSD_osname)) {
518 printf("This is %s version %s\n", ostype, osrelease);
519 printf("This version of AFS is only for %s\n",
521 return EPROGMISMATCH;
523 if (sysent[AFS_SYSCALL].sy_call == afs3_syscall
524 || sysent[AFS_SYSCALL].sy_call == afs_badcall) {
525 printf("AFS already loaded\n");
529 DISPATCH(lkmtp,cmd,ver,afs_vfs_load,afs_vfs_unload,lkm_nofunc);