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_xioctl(struct lwp
*, const void *, register_t
*);
114 extern int Afs_xsetgroups(struct lwp
*, const void *, register_t
*);
115 static int afs_badcall(struct lwp
*, const void *, register_t
*);
117 static int lkmid
= -1;
119 struct sysent afs_sysent
= { 6,
120 sizeof(struct afs_sysargs
),
124 static struct sysent old_sysent
;
125 static struct sysent old_setgroups
;
128 struct osi_vfs
*afs_globalVFS
;
129 struct vcache
*afs_globalVp
;
130 fsid_t afs_dynamic_fsid
;
132 int afs_mount(struct mount
*, const char *, void *, size_t *);
133 int afs_start(struct mount
*, int);
134 int afs_unmount(struct mount
*, int);
135 int afs_root(struct mount
*, struct vnode
**);
136 int afs_statvfs(struct mount
*, struct statvfs
*);
137 int afs_sync(struct mount
*, int, kauth_cred_t
);
139 void afs_reinit(void);
142 extern struct vnodeopv_desc afs_vnodeop_opv_desc
;
143 static const struct vnodeopv_desc
*afs_vnodeopv_descs
[] = {
144 &afs_vnodeop_opv_desc
,
148 struct vfsops afs_vfsops
= {
150 #ifdef AFS_NBSD50_ENV
151 0, /* vfs_min_mount_data */
157 (void *) eopnotsupp
, /* vfs_quotactl */
160 (void *) eopnotsupp
, /* vfs_vget */
161 (void *) eopnotsupp
, /* vfs_fhtovp */
162 (void *) eopnotsupp
, /* vfs_vptofh */
166 (void *) eopnotsupp
, /* vfs_mountroot */
167 (void *) eopnotsupp
, /* vfs_snapshot */
169 #ifdef AFS_NBSD50_ENV
170 (void *) eopnotsupp
, /* vfs_suspendctl */
171 genfs_renamelock_enter
, /* vfs_renamelock_enter */
172 genfs_renamelock_exit
, /* vfs_renamelock_exit */
173 (void *) eopnotsupp
, /* vfs_fsync */
176 0, /* vfs_refcount */
181 afs_nbsd_lookupname(const char *fnamep
, enum uio_seg segflg
, int followlink
,
182 struct vnode
**compvpp
)
188 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
189 afs_warn("afs_nbsd_lookupname enter (%s)\n", fnamep
);
193 * Lookup pathname "fnamep", returning leaf in *compvpp. segflg says
194 * whether the pathname is user or system space.
197 niflag
= followlink
? FOLLOW
: NOFOLLOW
;
199 * NBSD50 seems to have stopped caring about the curproc of things.
202 #if defined(AFS_NBSD60_ENV)
203 struct pathbuf
*ipb
= NULL
;
204 ipb
= pathbuf_create(fnamep
);
205 NDINIT(&nd
, LOOKUP
, niflag
, ipb
);
206 #elif defined(AFS_NBSD50_ENV)
207 NDINIT(&nd
, LOOKUP
, niflag
, segflg
, fnamep
);
209 NDINIT(&nd
, LOOKUP
, niflag
, segflg
, fnamep
, osi_curproc());
211 if ((error
= namei(&nd
))) {
216 #if defined(AFS_NBSD60_ENV)
217 pathbuf_destroy(ipb
);
223 afs_start(struct mount
*mp
, int flags
)
225 return (0); /* nothing to do? */
230 return; /* nothing to do? */
234 afs_mount(struct mount
*mp
, const char *path
, void *data
,
237 /* ndp contains the mounted-from device. Just ignore it.
238 * we also don't care about our proc struct. */
241 AFS_STATCNT(afs_mount
);
243 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
244 afs_warn("afs_mount enter\n");
247 if (mp
->mnt_flag
& MNT_UPDATE
)
250 if (afs_globalVFS
!= NULL
) {
251 /* Don't allow remounts */
256 #ifdef AFS_DISCON_ENV
257 /* initialize the vcache entries before we start using them */
259 /* XXX find a better place for this if possible */
260 init_vcache_entries();
263 mp
->mnt_stat
.f_bsize
= 8192;
264 mp
->mnt_stat
.f_frsize
= 8192;
265 mp
->mnt_stat
.f_iosize
= 8192;
266 mp
->mnt_fs_bshift
= DEV_BSHIFT
;
267 mp
->mnt_dev_bshift
= DEV_BSHIFT
;
269 afs_dynamic_fsid
= mp
->mnt_stat
.f_fsidx
;
270 (void)copyinstr(path
, mp
->mnt_stat
.f_mntonname
, MNAMELEN
- 1,
272 memset(mp
->mnt_stat
.f_mntonname
+ size
, 0, MNAMELEN
- size
);
273 memset(mp
->mnt_stat
.f_mntfromname
, 0, MNAMELEN
);
274 strcpy(mp
->mnt_stat
.f_mntfromname
, "AFS");
275 /* null terminated string "AFS" will fit, just leave it be. */
276 strcpy(mp
->mnt_stat
.f_fstypename
, AFS_MOUNT_AFS
);
278 (void)afs_statvfs(mp
, &mp
->mnt_stat
);
280 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
281 afs_warn("afs_mount exit\n");
288 afs_unmount(struct mount
*mp
, int mntflags
)
290 AFS_STATCNT(afs_unmount
);
291 #ifdef AFS_DISCON_ENV
294 if (afs_globalVFS
== NULL
) {
295 printf("afs already unmounted\n");
299 vrele(AFSTOV(afs_globalVp
));
302 vflush(mp
, NULLVP
, 0); /* don't support forced */
304 afs_globalVFS
= NULL
;
305 afs_cold_shutdown
= 1;
306 afs_shutdown(); /* XXX */
311 printf("AFS unmounted.\n");
315 #ifndef AFS_NBSD60_ENV
317 afs_badcall(struct lwp
*l
, const void *xx
, register_t
*yy
)
324 afs_root(struct mount
*mp
, struct vnode
**vpp
)
326 struct vrequest treq
;
331 AFS_STATCNT(afs_root
);
333 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
334 int glocked
= ISAFS_GLOCK();
335 afs_warn("afs_root enter, glocked==%d\n", glocked
);
340 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
341 afs_warn("afs_root: glocked\n");
346 if (afs_globalVp
&& (afs_globalVp
->f
.states
& CStatd
)) {
356 if (!(code
= afs_InitReq(&treq
, osi_curcred()))
357 && !(code
= afs_CheckInit())) {
358 tvp
= afs_GetVCache(&afs_rootFid
, &treq
, NULL
, NULL
);
373 struct vnode
*vp
= AFSTOV(tvp
);
380 if (!VOP_ISLOCKED(*vpp
))
381 code
= vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
);
383 if (!afs_globalVp
|| !(afs_globalVp
->f
.states
& CStatd
) ||
384 tvp
!= afs_globalVp
) {
392 vp
->v_vflag
|= VV_ROOT
;
393 if (afs_globalVFS
!= mp
)
399 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
400 afs_warn("afs_root exit\n");
407 afs_statvfs(struct mount
*mp
, struct statvfs
*abp
)
409 AFS_STATCNT(afs_statfs
);
411 if ((afs_debug
& AFSDEB_VNLAYER
) != 0) {
412 afs_warn("afs_statvfs enter\n");
415 /* thank you, NetBSD */
416 copy_statvfs_info(abp
, mp
);
418 /* not actually sure which we really must set, but
419 * pretty sure of the right values (and in 40, none touched by
420 * the above convenience function) */
421 abp
->f_bsize
= mp
->osi_vfs_bsize
;
422 abp
->f_frsize
= mp
->osi_vfs_bsize
;
423 abp
->f_iosize
= mp
->osi_vfs_bsize
;
425 abp
->f_blocks
= abp
->f_bfree
= abp
->f_bavail
= abp
->f_files
=
426 abp
->f_ffree
= AFS_VFS_FAKEFREE
;
432 afs_sync(struct mount
*mp
, int waitfor
, kauth_cred_t cred
)
434 AFS_STATCNT(afs_sync
);
435 #if defined(AFS_DISCON_ENV)
436 /* Can't do this in OpenBSD 2.7, it faults when called from apm_suspend() */
437 store_dirty_vcaches();
455 #ifndef AFS_NBSD60_ENV
459 * declare the filesystem
461 MOD_VFS("afs", -1, &afs_vfsops
);
464 afs_vfs_load(struct lkm_table
*lkmtp
, int cmd
)
467 if (sysent
[AFS_SYSCALL
].sy_call
!= sys_lkmnosys
) {
468 printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n",
473 old_sysent
= sysent
[AFS_SYSCALL
];
474 sysent
[AFS_SYSCALL
] = afs_sysent
;
475 old_setgroups
= sysent
[SYS_setgroups
];
476 sysent
[SYS_setgroups
].sy_call
= Afs_xsetgroups
;
478 old_ioctl
= sysent
[SYS_ioctl
];
479 sysent
[SYS_ioctl
].sy_call
= afs_xioctl
;
482 aprint_verbose("OpenAFS loaded\n");
488 afs_vfs_unload(struct lkm_table
*lktmp
, int cmd
)
493 if (sysent
[AFS_SYSCALL
].sy_call
!= afs_sysent
.sy_call
) {
494 printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n",
499 sysent
[AFS_SYSCALL
] = old_sysent
;
500 sysent
[SYS_setgroups
] = old_setgroups
;
502 sysent
[SYS_ioctl
] = old_ioctl
;
504 printf("OpenAFS unloaded\n");
509 int libafs_lkmentry(struct lkm_table
*, int, int);
512 libafs_lkmentry(struct lkm_table
*lkmtp
, int cmd
, int ver
)
514 if (cmd
== LKM_E_LOAD
) {
515 if (sysent
[AFS_SYSCALL
].sy_call
== afs3_syscall
516 || sysent
[AFS_SYSCALL
].sy_call
== afs_badcall
) {
517 printf("AFS already loaded\n");
522 DISPATCH(lkmtp
, cmd
, ver
, afs_vfs_load
, afs_vfs_unload
, lkm_nofunc
);