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>
102 #ifndef AFS_NBSD60_ENV
105 #include <sys/namei.h>
106 #include <miscfs/genfs/genfs.h>
110 #ifndef AFS_NBSD60_ENV
111 extern int sys_lkmnosys(struct lwp *, const void *, register_t *);
112 extern int afs3_syscall(struct lwp *, const void *, register_t *);
113 extern int Afs_xsetgroups(struct lwp *, const void *, register_t *);
114 static int afs_badcall(struct lwp *, const void *, register_t *);
116 static int lkmid = -1;
118 struct sysent afs_sysent = { 6,
119 sizeof(struct afs_sysargs),
123 static struct sysent old_sysent;
124 static struct sysent old_setgroups;
127 struct osi_vfs *afs_globalVFS;
128 struct vcache *afs_globalVp;
129 fsid_t afs_dynamic_fsid;
131 int afs_mount(struct mount *, const char *, void *, size_t *);
132 int afs_start(struct mount *, int);
133 int afs_unmount(struct mount *, int);
134 int afs_root(struct mount *, struct vnode **);
135 int afs_statvfs(struct mount *, struct statvfs *);
136 int afs_sync(struct mount *, int, kauth_cred_t);
138 void afs_reinit(void);
141 extern struct vnodeopv_desc afs_vnodeop_opv_desc;
142 static const struct vnodeopv_desc *afs_vnodeopv_descs[] = {
143 &afs_vnodeop_opv_desc,
147 struct vfsops afs_vfsops = {
149 #ifdef AFS_NBSD50_ENV
150 0, /* vfs_min_mount_data */
156 (void *) eopnotsupp, /* vfs_quotactl */
159 (void *) eopnotsupp, /* vfs_vget */
160 (void *) eopnotsupp, /* vfs_fhtovp */
161 (void *) eopnotsupp, /* vfs_vptofh */
165 (void *) eopnotsupp, /* vfs_mountroot */
166 (void *) eopnotsupp, /* vfs_snapshot */
168 #ifdef AFS_NBSD50_ENV
169 (void *) eopnotsupp, /* vfs_suspendctl */
170 genfs_renamelock_enter, /* vfs_renamelock_enter */
171 genfs_renamelock_exit, /* vfs_renamelock_exit */
172 (void *) eopnotsupp, /* vfs_fsync */
175 0, /* vfs_refcount */
180 afs_nbsd_lookupname(const char *fnamep, enum uio_seg segflg, int followlink,
181 struct vnode **compvpp)
187 if ((afs_debug & AFSDEB_VNLAYER) != 0) {
188 afs_warn("afs_nbsd_lookupname enter (%s)\n", fnamep);
192 * Lookup pathname "fnamep", returning leaf in *compvpp. segflg says
193 * whether the pathname is user or system space.
196 niflag = followlink ? FOLLOW : NOFOLLOW;
198 * NBSD50 seems to have stopped caring about the curproc of things.
201 #if defined(AFS_NBSD60_ENV)
202 struct pathbuf *ipb = NULL;
203 ipb = pathbuf_create(fnamep);
204 NDINIT(&nd, LOOKUP, niflag, ipb);
205 #elif defined(AFS_NBSD50_ENV)
206 NDINIT(&nd, LOOKUP, niflag, segflg, fnamep);
208 NDINIT(&nd, LOOKUP, niflag, segflg, fnamep, osi_curproc());
210 if ((error = namei(&nd))) {
215 #if defined(AFS_NBSD60_ENV)
216 pathbuf_destroy(ipb);
222 afs_start(struct mount *mp, int flags)
224 return (0); /* nothing to do? */
229 return; /* nothing to do? */
233 afs_mount(struct mount *mp, const char *path, void *data,
236 /* ndp contains the mounted-from device. Just ignore it.
237 * we also don't care about our proc struct. */
240 AFS_STATCNT(afs_mount);
242 if ((afs_debug & AFSDEB_VNLAYER) != 0) {
243 afs_warn("afs_mount enter\n");
246 if (mp->mnt_flag & MNT_UPDATE)
249 if (afs_globalVFS != NULL) {
250 /* Don't allow remounts */
255 #ifdef AFS_DISCON_ENV
256 /* initialize the vcache entries before we start using them */
258 /* XXX find a better place for this if possible */
259 init_vcache_entries();
262 mp->mnt_stat.f_bsize = 8192;
263 mp->mnt_stat.f_frsize = 8192;
264 mp->mnt_stat.f_iosize = 8192;
265 mp->mnt_fs_bshift = DEV_BSHIFT;
266 mp->mnt_dev_bshift = DEV_BSHIFT;
268 afs_dynamic_fsid = mp->mnt_stat.f_fsidx;
269 (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1,
271 memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
272 memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
273 strcpy(mp->mnt_stat.f_mntfromname, "AFS");
274 /* null terminated string "AFS" will fit, just leave it be. */
275 strcpy(mp->mnt_stat.f_fstypename, AFS_MOUNT_STR);
277 (void)afs_statvfs(mp, &mp->mnt_stat);
279 if ((afs_debug & AFSDEB_VNLAYER) != 0) {
280 afs_warn("afs_mount exit\n");
287 afs_unmount(struct mount *mp, int mntflags)
289 AFS_STATCNT(afs_unmount);
290 #ifdef AFS_DISCON_ENV
293 if (afs_globalVFS == NULL) {
294 printf("afs already unmounted\n");
298 vrele(AFSTOV(afs_globalVp));
301 vflush(mp, NULLVP, 0); /* don't support forced */
303 afs_globalVFS = NULL;
304 afs_shutdown(AFS_COLD);
309 printf("AFS unmounted.\n");
313 #ifndef AFS_NBSD60_ENV
315 afs_badcall(struct lwp *l, const void *xx, register_t *yy)
322 afs_root(struct mount *mp, struct vnode **vpp)
324 struct vrequest treq;
329 AFS_STATCNT(afs_root);
331 if ((afs_debug & AFSDEB_VNLAYER) != 0) {
332 int glocked = ISAFS_GLOCK();
333 afs_warn("afs_root enter, glocked==%d\n", glocked);
338 if ((afs_debug & AFSDEB_VNLAYER) != 0) {
339 afs_warn("afs_root: glocked\n");
344 if (afs_globalVp && (afs_globalVp->f.states & CStatd)) {
354 if (!(code = afs_InitReq(&treq, osi_curcred()))
355 && !(code = afs_CheckInit())) {
356 tvp = afs_GetVCache(&afs_rootFid, &treq);
371 struct vnode *vp = AFSTOV(tvp);
378 if (!VOP_ISLOCKED(*vpp))
379 code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
381 if (!afs_globalVp || !(afs_globalVp->f.states & CStatd) ||
382 tvp != afs_globalVp) {
390 vp->v_vflag |= VV_ROOT;
391 if (afs_globalVFS != mp)
397 if ((afs_debug & AFSDEB_VNLAYER) != 0) {
398 afs_warn("afs_root exit\n");
405 afs_statvfs(struct mount *mp, struct statvfs *abp)
407 AFS_STATCNT(afs_statfs);
409 if ((afs_debug & AFSDEB_VNLAYER) != 0) {
410 afs_warn("afs_statvfs enter\n");
413 /* thank you, NetBSD */
414 copy_statvfs_info(abp, mp);
416 /* not actually sure which we really must set, but
417 * pretty sure of the right values (and in 40, none touched by
418 * the above convenience function) */
419 abp->f_bsize = mp->osi_vfs_bsize;
420 abp->f_frsize = mp->osi_vfs_bsize;
421 abp->f_iosize = mp->osi_vfs_bsize;
423 abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files =
424 abp->f_ffree = AFS_VFS_FAKEFREE;
430 afs_sync(struct mount *mp, int waitfor, kauth_cred_t cred)
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();
453 #ifndef AFS_NBSD60_ENV
457 * declare the filesystem
459 MOD_VFS("afs", -1, &afs_vfsops);
462 afs_vfs_load(struct lkm_table *lkmtp, int cmd)
465 if (sysent[AFS_SYSCALL].sy_call != sys_lkmnosys) {
466 printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n",
471 old_sysent = sysent[AFS_SYSCALL];
472 sysent[AFS_SYSCALL] = afs_sysent;
473 old_setgroups = sysent[SYS_setgroups];
474 sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
476 old_ioctl = sysent[SYS_ioctl];
477 sysent[SYS_ioctl].sy_call = afs_xioctl;
480 aprint_verbose("OpenAFS loaded\n");
486 afs_vfs_unload(struct lkm_table *lktmp, int cmd)
491 if (sysent[AFS_SYSCALL].sy_call != afs_sysent.sy_call) {
492 printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n",
497 sysent[AFS_SYSCALL] = old_sysent;
498 sysent[SYS_setgroups] = old_setgroups;
500 sysent[SYS_ioctl] = old_ioctl;
502 printf("OpenAFS unloaded\n");
507 int libafs_lkmentry(struct lkm_table *, int, int);
510 libafs_lkmentry(struct lkm_table *lkmtp, int cmd, int ver)
512 if (cmd == LKM_E_LOAD) {
513 if (sysent[AFS_SYSCALL].sy_call == afs3_syscall
514 || sysent[AFS_SYSCALL].sy_call == afs_badcall) {
515 printf("AFS already loaded\n");
520 DISPATCH(lkmtp, cmd, ver, afs_vfs_load, afs_vfs_unload, lkm_nofunc);