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 the OpenAFS 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"
97 #include "afs/sysincludes.h" /* Standard vendor system headers */
98 #include "afs/afsincludes.h" /* Afs-based standard headers */
99 #include "afs/afs_stats.h" /* statistics */
101 #include <sys/conf.h>
102 #include <sys/exec.h>
104 #include <sys/namei.h>
105 #include <sys/syscall.h>
106 #include <sys/syscallargs.h>
108 /* from /usr/src/sys/kern/vfs_subr.c */
109 extern void insmntque(struct vnode *, struct mount *);
111 extern int sys_lkmnosys(), afs_xioctl(), Afs_xsetgroups();
113 static int lkmid = -1;
114 static int afs_badcall(struct proc *p, void *xx, register_t * yy);
115 static struct sysent old_sysent;
117 struct osi_vfs *afs_globalVFS;
118 struct vcache *afs_globalVp;
134 struct vfsops afs_vfsops = {
151 afs_obsd_lookupname(char *fnamep, enum uio_seg segflg, int followlink,
152 struct vnode **compvpp)
159 * Lookup pathname "fnamep", returning leaf in *compvpp. segflg says
160 * whether the pathname is user or system space.
163 niflag = followlink ? FOLLOW : NOFOLLOW;
164 NDINIT(&nd, LOOKUP, niflag, segflg, fnamep, osi_curproc());
165 if ((error = namei(&nd)))
190 afs_fhtovp(mp, fhp, vpp)
209 afs_start(mp, flags, p)
214 return (0); /* nothing to do. ? */
218 afs_mount(mp, path, data, ndp, p)
222 struct nameidata *ndp;
225 /* ndp contains the mounted-from device. Just ignore it.
226 * we also don't care about our proc struct. */
229 if (mp->mnt_flag & MNT_UPDATE)
233 /* Don't allow remounts */
237 AFS_STATCNT(afs_mount);
240 /* initialize the vcache entries before we start using them */
242 /* XXX find a better place for this if possible */
244 mp->osi_vfs_bsize = 8192;
245 mp->osi_vfs_fsid.val[0] = AFS_VFSMAGIC; /* magic */
246 mp->osi_vfs_fsid.val[1] = (int)AFS_VFSFSID;
248 #if defined(AFS_OBSD53_ENV)
249 bzero(mp->mnt_stat.f_mntonname, MNAMELEN);
250 strlcpy(mp->mnt_stat.f_mntonname, path, MNAMELEN);
252 (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
253 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
255 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
256 strcpy(mp->mnt_stat.f_mntfromname, "AFS");
257 /* null terminated string "AFS" will fit, just leave it be. */
258 strcpy(mp->mnt_stat.f_fstypename, MOUNT_AFS);
260 (void)afs_statfs(mp, &mp->mnt_stat);
266 afs_unmount(afsp, flags, p)
271 extern int sys_ioctl(), sys_setgroups();
275 for (vp = LIST_FIRST(&afsp->mnt_vnodelist); vp != NULL;
276 vp = LIST_NEXT(vp, v_mntvnodes)) {
277 if (vp->v_usecount) return EBUSY;
280 AFS_STATCNT(afs_unmount);
281 if (afs_globalVFS == NULL) {
282 printf("afs already unmounted\n");
286 vrele(AFSTOV(afs_globalVp));
289 vflush(afsp, NULLVP, 0); /* don't support forced */
290 afsp->mnt_data = NULL;
293 afs_cold_shutdown = 1;
294 afs_shutdown(); /* XXX */
297 /* give up syscall entries for ioctl & setgroups, which we've stolen */
298 sysent[SYS_ioctl].sy_call = sys_ioctl;
299 sysent[SYS_setgroups].sy_call = sys_setgroups;
301 /* give up the stolen syscall entry */
302 sysent[AFS_SYSCALL].sy_narg = 0;
303 sysent[AFS_SYSCALL].sy_argsize = 0;
304 sysent[AFS_SYSCALL].sy_call = afs_badcall;
306 ("AFS unmounted--use `/sbin/modunload -i %d' to unload before restarting AFS\n",
312 afs_badcall(struct proc *p, void *xx, register_t * yy)
317 #if defined(AFS_OBSD49_ENV)
318 extern struct vops afs_vops;
322 afs_obsd_getnewvnode(struct vcache *tvc)
324 #if defined(AFS_OBSD49_ENV)
325 while (getnewvnode(VT_AFS, afs_globalVFS, &afs_vops, &tvc->v)) {
327 while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) {
329 /* no vnodes available, force an alloc (limits be damned)! */
332 tvc->v->v_data = (void *)tvc;
336 afs_root(struct mount *mp, struct vnode **vpp)
338 struct vrequest treq;
342 AFS_STATCNT(afs_root);
345 if (!(code = afs_InitReq(&treq, osi_curcred()))
346 && !(code = afs_CheckInit())) {
347 tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
349 /* There is really no reason to over-hold this bugger--it's held
350 * by the root filesystem reference. */
351 if (afs_globalVp != tvp) {
352 #ifdef AFS_DONT_OVERHOLD_GLOBALVP
354 AFS_RELE(AFSTOV(afs_globalVp));
357 vref(AFSTOV(afs_globalVp));
359 AFSTOV(tvp)->v_flag |= VROOT;
368 vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curproc); /* return it locked */
373 afs_statfs(struct osi_vfs *afsp, struct statfs *abp)
375 AFS_STATCNT(afs_statfs);
376 abp->f_bsize = afsp->osi_vfs_bsize;
379 * Fake a high number below to satisfy programs that use the ustat (for
380 * * AIX), or statfs (for the rest) call to make sure that there's
381 * enough * space in the device partition before storing something there
384 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
385 abp->f_ffree = 9000000;
386 abp->f_fsid.val[0] = AFS_VFSMAGIC; /* magic */
387 abp->f_fsid.val[1] = (int)AFS_VFSFSID;
392 afs_sync(struct osi_vfs *afsp)
394 AFS_STATCNT(afs_sync);
405 if (vp->v_usecount < 0) {
406 vprint("bad usecount", vp);
409 error = vget(vp, lfl, curproc);
410 if (!error && vp->v_usecount == 1) {
411 /* vget() took it off the freelist; put it on our mount queue */
412 insmntque(vp, afs_globalVFS);
417 extern struct vfsops afs_vfsops;
418 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
420 static struct vfsconf afs_vfsconf = {
430 MOD_VFS("afs", 0, &afs_vfsconf);
432 static char afsgenmem[] = "afsgenmem";
433 static char afsfidmem[] = "afsfidmem";
434 static char afsbhdrmem[] = "afsbhdrmem";
435 static char afsbfrmem[] = "afsbfrmem";
440 old_sysent = sysent[AFS_SYSCALL];
442 sysent[AFS_SYSCALL].sy_call = afs3_syscall;
443 sysent[AFS_SYSCALL].sy_narg = 6;
444 sysent[AFS_SYSCALL].sy_argsize = 6 * sizeof(long);
445 sysent[SYS_ioctl].sy_call = afs_xioctl;
446 sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
453 afs_vfs_load(struct lkm_table *lkmtp, int cmd)
455 extern char *memname[];
457 #if ! defined(AFS_OBSD49_ENV)
458 vfs_opv_init_explicit(&afs_vnodeop_opv_desc);
459 vfs_opv_init_default(&afs_vnodeop_opv_desc);
461 if (memname[M_AFSGENERIC] == NULL)
462 memname[M_AFSGENERIC] = afsgenmem;
463 if (memname[M_AFSFID] == NULL)
464 memname[M_AFSFID] = afsfidmem;
465 if (memname[M_AFSBUFHDR] == NULL)
466 memname[M_AFSBUFHDR] = afsbhdrmem;
467 if (memname[M_AFSBUFFER] == NULL)
468 memname[M_AFSBUFFER] = afsbfrmem;
470 printf("OpenAFS ($Revision$) lkm loaded\n");
475 afs_vfs_unload(struct lkm_table *lktmp, int cmd)
477 extern char *memname[];
481 if (sysent[SYS_ioctl].sy_call != sys_ioctl)
484 if (memname[M_AFSGENERIC] == afsgenmem)
485 memname[M_AFSGENERIC] = NULL;
486 if (memname[M_AFSFID] == afsfidmem)
487 memname[M_AFSFID] = NULL;
488 if (memname[M_AFSBUFHDR] == afsbhdrmem)
489 memname[M_AFSBUFHDR] = NULL;
490 if (memname[M_AFSBUFFER] == afsbfrmem)
491 memname[M_AFSBUFFER] = NULL;
493 sysent[AFS_SYSCALL] = old_sysent;
494 printf("OpenAFS unloaded\n");
499 libafs_lkmentry(struct lkm_table *lkmtp, int cmd, int ver)
501 if (cmd == LKM_E_LOAD) {
502 if (sysent[AFS_SYSCALL].sy_call == afs3_syscall
503 || sysent[AFS_SYSCALL].sy_call == afs_badcall) {
504 printf("AFS already loaded\n");
508 DISPATCH(lkmtp, cmd, ver, afs_vfs_load, afs_vfs_unload, lkm_nofunc);