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>
5 * Reported to NetBSD 4.0 by Matt Benjamin (matt@linuxbox.com)
7 * $Id: osi_vfsops.c,v 1.20 2005/03/08 21:58:04 shadow Exp $
12 the regents of the university of michigan
15 permission is granted to use, copy, create derivative works
16 and redistribute this software and such derivative works
17 for any purpose, so long as the name of the university of
18 michigan is not used in any advertising or publicity
19 pertaining to the use or distribution of this software
20 without specific, written prior authorization. if the
21 above copyright notice or any other identification of the
22 university of michigan is included in any copy of any
23 portion of this software, then the disclaimer below must
26 this software is provided as is, without representation
27 from the university of michigan as to its fitness for any
28 purpose, and without warranty by the university of
29 michigan of any kind, either express or implied, including
30 without limitation the implied warranties of
31 merchantability and fitness for a particular purpose. the
32 regents of the university of michigan shall not be liable
33 for any damages, including special, indirect, incidental, or
34 consequential damages, with respect to any claim arising
35 out of or in connection with the use of the software, even
36 if it has been or is hereafter advised of the possibility of
41 Copyright 1995 Massachusetts Institute of Technology. All Rights
44 You are hereby granted a worldwide, irrevocable, paid-up, right and
45 license to use, execute, display, modify, copy and distribute MIT's
46 Modifications, provided that (i) you abide by the terms and conditions
47 of the OpenAFS License Agreement, and (ii) you do not use the name
48 of MIT in any advertising or publicity without the prior written consent
49 of MIT. MIT disclaims all liability for your use of MIT's
50 Modifications. MIT's Modifications are provided "AS IS" WITHOUT
51 WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO,
52 ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
57 * Some code cribbed from ffs_vfsops and other NetBSD sources, which
61 * Copyright (c) 1989, 1991, 1993, 1994
62 * The Regents of the University of California. All rights reserved.
64 * Redistribution and use in source and binary forms, with or without
65 * modification, are permitted provided that the following conditions
67 * 1. Redistributions of source code must retain the above copyright
68 * notice, this list of conditions and the following disclaimer.
69 * 2. Redistributions in binary form must reproduce the above copyright
70 * notice, this list of conditions and the following disclaimer in the
71 * documentation and/or other materials provided with the distribution.
72 * 3. All advertising materials mentioning features or use of this software
73 * must display the following acknowledgement:
74 * This product includes software developed by the University of
75 * California, Berkeley and its contributors.
76 * 4. Neither the name of the University nor the names of its contributors
77 * may be used to endorse or promote products derived from this software
78 * without specific prior written permission.
80 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
81 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
82 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
83 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
84 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
85 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
86 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
87 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
88 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
89 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
94 #include <afsconfig.h>
95 #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/ioctl.h>
103 #include <sys/namei.h>
105 extern unsigned long long afs_debug;
108 /* from /usr/src/sys/kern/vfs_subr.c */
109 extern void insmntque(struct vnode *, struct mount *);
111 extern int sys_lkmnosys(), afs3_syscall(), afs_xioctl(), Afs_xsetgroups();
113 static int lkmid = -1;
114 static int afs_badcall(struct lwp *, void *, register_t *);
118 newcall(l, v, retval)
123 struct afs_sysargs *uap = v;
125 printf("kmod: newcall: %ld %ld %ld %ld\n",
126 SCARG(uap, syscall), SCARG(uap, parm1),
127 SCARG(uap, parm2), SCARG(uap, parm3));
132 struct sysent afs_sysent = { 6,
133 sizeof(struct afs_sysargs),
137 static struct sysent old_sysent;
139 struct osi_vfs *afs_globalVFS;
140 struct vcache *afs_globalVp;
141 fsid_t afs_dynamic_fsid;
143 int afs_mount(struct mount *, const char *, void *,
144 struct nameidata *, struct lwp *);
145 int afs_start(struct mount *, int, struct lwp *);
146 int afs_unmount(struct mount *, int, struct lwp *);
147 int afs_root(struct mount *, struct vnode **);
148 int afs_quotactl(struct mount *, int, uid_t, void *, struct lwp *);
149 int afs_statvfs(struct mount *, struct statvfs *, struct lwp *);
150 int afs_sync(struct mount *, int, kauth_cred_t, struct lwp *);
151 int afs_vget(struct mount *, ino_t, struct vnode **);
153 void afs_reinit(void);
156 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
157 static const struct vnodeopv_desc *afs_vnodeopv_descs[] = {
158 &afs_vnodeop_opv_desc,
162 struct vfsops afs_vfsops = {
164 #ifdef AFS_NBSD50_ENV
165 0, /* vfs_min_mount_data */
175 (void *) eopnotsupp, /* vfs_fhtovp */
176 (void *) eopnotsupp, /* vfs_vptofh */
180 (int (*) (void)) eopnotsupp, /* mountroot */
181 (int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp, /* vfs_snapshot */
183 #ifdef AFS_NBSD50_ENV
184 (int (*)(struct mount *, int)) eopnotsupp, /* vfs_suspendctl */
185 (int (*)(struct mount *)) eopnotsupp, /* vfs_renamelock_enter */
186 (void *) eopnotsupp, /* vfs_renamelock_exit */
187 (int (*)(struct vnode*, int)) eopnotsupp, /* vfs_fsync */
190 0, /* vfs_refcount */
194 VFS_ATTACH(afs_vfsops);
197 afs_nbsd_lookupname(char *fnamep, enum uio_seg segflg, int followlink,
198 struct vnode **compvpp)
204 afs_warn("afs_nbsd_lookupname enter (%s)\n", fnamep);
207 * Lookup pathname "fnamep", returning leaf in *compvpp. segflg says
208 * whether the pathname is user or system space.
211 niflag = followlink ? FOLLOW : NOFOLLOW;
213 * NBSD50 seems to have stopped caring about the curproc of things.
216 #ifdef AFS_NBSD50_ENV
217 NDINIT(&nd, LOOKUP, niflag, segflg, fnamep);
219 NDINIT(&nd, LOOKUP, niflag, segflg, fnamep, osi_curproc());
221 if ((error = namei(&nd)))
228 afs_quotactl(struct mount *mp, int cmd, uid_t uid,
229 void *arg, struct lwp *l)
241 afs_start(struct mount *mp, int flags, struct lwp *l)
243 return (0); /* nothing to do? */
248 return; /* nothing to do? */
252 afs_mount(struct mount *mp, const char *path, void *data,
253 struct nameidata *ndp, struct lwp *l)
255 /* ndp contains the mounted-from device. Just ignore it.
256 * we also don't care about our proc struct. */
259 AFS_STATCNT(afs_mount);
261 afs_warn("afs_mount enter\n");
263 if (mp->mnt_flag & MNT_UPDATE)
267 /* Don't allow remounts */
272 #ifdef AFS_DISCON_ENV
273 /* initialize the vcache entries before we start using them */
275 /* XXX find a better place for this if possible */
276 init_vcache_entries();
279 mp->mnt_stat.f_bsize = 8192;
280 mp->mnt_stat.f_frsize = 8192;
281 mp->mnt_stat.f_iosize = 8192;
283 mp->osi_vfs_fsid.val[0] = AFS_VFSMAGIC; /* magic */
284 mp->osi_vfs_fsid.val[1] = (int)AFS_VFSFSID;
287 afs_dynamic_fsid = mp->mnt_stat.f_fsidx;
289 (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1,
291 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
292 bzero(mp->mnt_stat.f_mntfromname, MNAMELEN);
293 strcpy(mp->mnt_stat.f_mntfromname, "AFS");
294 /* null terminated string "AFS" will fit, just leave it be. */
295 strcpy(mp->mnt_stat.f_fstypename, AFS_MOUNT_AFS);
297 (void)afs_statvfs(mp, &mp->mnt_stat, l);
299 afs_warn("afs_mount exit\n");
305 afs_unmount(struct mount *mp, int mntflags, struct lwp *l)
307 extern int sys_ioctl(), sys_setgroups();
309 AFS_STATCNT(afs_unmount);
310 #ifdef AFS_DISCON_ENV
313 if (afs_globalVFS == NULL) {
314 printf("afs already unmounted\n");
318 vrele(AFSTOV(afs_globalVp));
321 vflush(mp, NULLVP, 0); /* don't support forced */
325 afs_cold_shutdown = 1;
326 afs_shutdown(); /* XXX */
330 ("AFS unmounted--use `/sbin/modunload -i %d' to unload before restarting AFS\n",
336 afs_badcall(struct lwp *l, void *xx, register_t * yy)
342 afs_root(struct mount *mp, struct vnode **vpp)
344 struct vrequest treq;
348 AFS_STATCNT(afs_root);
350 glocked = ISAFS_GLOCK();
351 afs_warn("afs_root enter, glocked==%d\n", glocked);
355 afs_warn("glocked\n");
357 if (!(code = afs_InitReq(&treq, osi_curcred()))
358 && !(code = afs_CheckInit())) {
360 afs_warn("afs_root: initReq && CheckInit: code==%d\n", code);
362 tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
363 afs_warn("afs_root: GetVCache: tvp==%lx\n", tvp);
365 /* There is really no reason to over-hold this bugger--it's held
366 * by the root filesystem reference. */
367 if (afs_globalVp != tvp) {
368 #ifdef AFS_DONT_OVERHOLD_GLOBALVP
370 AFS_RELE(AFSTOV(afs_globalVp));
373 VREF(AFSTOV(afs_globalVp));
375 /* v_flag no longer exists... mattjsm */
376 #ifdef AFS_NBSD50_ENV
377 AFSTOV(tvp)->v_vflag |= VV_ROOT;
379 AFSTOV(tvp)->v_flag |= VROOT;
388 afs_warn("afs_root: gunlocked\n");
391 if (!VOP_ISLOCKED(*vpp))
392 vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); /* return it locked */
395 afs_warn("afs_root exit\n");
401 afs_statvfs(struct mount *mp, struct statvfs *abp, struct lwp *l)
403 AFS_STATCNT(afs_statfs);
405 afs_warn("afs_statvfs enter\n");
407 /* thank you, NetBSD */
408 copy_statvfs_info(abp, mp);
410 /* not actually sure which we really must set, but
411 * pretty sure of the right values (and in 40, none touched by
412 * the above convenience function) */
413 abp->f_bsize = mp->osi_vfs_bsize;
414 abp->f_frsize = mp->osi_vfs_bsize;
415 abp->f_iosize = mp->osi_vfs_bsize;
418 * Fake a high number below to satisfy programs that use the ustat (for
419 * * AIX), or statfs (for the rest) call to make sure that there's
420 * enough * space in the device partition before storing something there
423 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
424 abp->f_ffree = 9000000;
430 afs_sync(struct mount *mp, int waitfor, kauth_cred_t cred, struct lwp *l)
432 AFS_STATCNT(afs_sync);
433 #if defined(AFS_DISCON_ENV)
434 /* Can't do this in OpenBSD 2.7, it faults when called from apm_suspend() */
435 store_dirty_vcaches();
441 afs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
462 * declare the filesystem
464 MOD_VFS("afs", -1, &afs_vfsops);
467 static char afsgenmem[] = "afsgenmem";
468 static char afsfidmem[] = "afsfidmem";
469 static char afsbhdrmem[] = "afsbhdrmem";
470 static char afsbfrmem[] = "afsbfrmem";
474 afs_vfs_load(struct lkm_table *lkmtp, int cmd)
477 extern char *memname[];
479 if (memname[M_AFSGENERIC] == NULL)
480 memname[M_AFSGENERIC] = afsgenmem;
481 if (memname[M_AFSFID] == NULL)
482 memname[M_AFSFID] = afsfidmem;
483 if (memname[M_AFSBUFHDR] == NULL)
484 memname[M_AFSBUFHDR] = afsbhdrmem;
485 if (memname[M_AFSBUFFER] == NULL)
486 memname[M_AFSBUFFER] = afsbfrmem;
489 if (sysent[AFS_SYSCALL].sy_call != sys_nosys) {
490 printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n",
495 old_sysent = sysent[AFS_SYSCALL];
496 sysent[AFS_SYSCALL] = afs_sysent;
498 printf("OpenAFS lkm loaded id: %d\n", lkmid);
504 afs_vfs_unload(struct lkm_table *lktmp, int cmd)
507 extern char *memname[];
513 if (memname[M_AFSGENERIC] == afsgenmem)
514 memname[M_AFSGENERIC] = NULL;
515 if (memname[M_AFSFID] == afsfidmem)
516 memname[M_AFSFID] = NULL;
517 if (memname[M_AFSBUFHDR] == afsbhdrmem)
518 memname[M_AFSBUFHDR] = NULL;
519 if (memname[M_AFSBUFFER] == afsbfrmem)
520 memname[M_AFSBUFFER] = NULL;
523 if (sysent[AFS_SYSCALL].sy_call != afs_sysent.sy_call) {
524 printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n",
529 sysent[AFS_SYSCALL] = old_sysent;
530 printf("OpenAFS unloaded\n");
536 libafs_lkmentry(struct lkm_table *lkmtp, int cmd, int ver)
538 if (cmd == LKM_E_LOAD) {
539 if (sysent[AFS_SYSCALL].sy_call == afs3_syscall
540 || sysent[AFS_SYSCALL].sy_call == afs_badcall) {
541 printf("AFS already loaded\n");
547 afs_debug = AFSDEB_VNLAYER;
550 DISPATCH(lkmtp, cmd, ver, afs_vfs_load, afs_vfs_unload, lkm_nofunc);