From 750b8659281988a138db6f26f53d747175895186 Mon Sep 17 00:00:00 2001 From: "Jonathan A. Kollasch" Date: Mon, 16 May 2011 14:30:24 +0000 Subject: [PATCH] Port cache manager to NetBSD-5 and NetBSD-current Change-Id: I3d1aa0b22bb8533718f48bd4424743299d5de019 Reviewed-on: http://gerrit.openafs.org/4661 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- src/afs/NBSD/osi_file.c | 21 +- src/afs/NBSD/osi_groups.c | 78 ++-- src/afs/NBSD/osi_kmod.c | 133 +++++++ src/afs/NBSD/osi_machdep.h | 119 +----- src/afs/NBSD/osi_misc.c | 107 +---- src/afs/NBSD/osi_sleep.c | 226 ++++++++++- src/afs/NBSD/osi_vcache.c | 50 +-- src/afs/NBSD/osi_vfsops.c | 327 +++++++-------- src/afs/NBSD/osi_vm.c | 80 +++- src/afs/NBSD/osi_vnodeops.c | 812 +++++++++++++++++++------------------- src/afs/VNOPS/afs_vnop_read.c | 5 + src/afs/VNOPS/afs_vnop_readdir.c | 37 +- src/afs/VNOPS/afs_vnop_strategy.c | 16 +- src/afs/VNOPS/afs_vnop_write.c | 4 + src/afs/afs.h | 11 +- src/afs/afs_daemons.c | 19 - src/afs/afs_init.c | 4 +- src/afs/afs_osi.c | 2 +- src/afs/afs_osi_alloc.c | 3 - src/afs/afs_osi_pag.c | 12 +- src/afs/afs_pioctl.c | 45 ++- src/afs/afs_prototypes.h | 25 +- src/afs/afs_syscall.c | 7 +- src/afs/sysincludes.h | 11 +- src/config/param.nbsd50.h | 14 +- src/config/param.nbsd60.h | 14 +- src/dir/dir.c | 2 +- src/rx/NBSD/rx_kmutex.c | 57 ++- src/rx/NBSD/rx_kmutex.h | 60 ++- src/rx/NBSD/rx_knet.c | 9 +- src/rx/rx_kcommon.c | 6 + src/rx/rx_packet.c | 5 + 32 files changed, 1295 insertions(+), 1026 deletions(-) create mode 100644 src/afs/NBSD/osi_kmod.c diff --git a/src/afs/NBSD/osi_file.c b/src/afs/NBSD/osi_file.c index 55a10d7..d162f6e 100644 --- a/src/afs/NBSD/osi_file.c +++ b/src/afs/NBSD/osi_file.c @@ -16,7 +16,6 @@ int afs_osicred_initialized; -afs_ucred_t afs_osi_cred; afs_lock_t afs_xosi; /* lock is for tvattr */ extern struct osi_dev cacheDev; extern struct mount *afs_cacheVfsp; @@ -42,7 +41,11 @@ osi_UFSOpen(afs_dcache_id_t *ainode) osi_FreeSmallSpace(afile); osi_Panic("UFSOpen: igetinode failed"); } +#if defined(AFS_NBSD60_ENV) + VOP_UNLOCK(vp); +#else VOP_UNLOCK(vp, 0); +#endif afile->vnode = vp; afile->size = VTOI(vp)->i_ffs1_size; afile->offset = 0; @@ -111,12 +114,16 @@ osi_UFSTruncate(struct osi_file *afile, afs_int32 asize) AFS_GUNLOCK(); VOP_LOCK(afile->vnode, LK_EXCLUSIVE | LK_RETRY); #ifdef AFS_NBSD50_ENV - code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp); + code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp); #else code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp, osi_curproc()); #endif +#ifdef AFS_NBSD60_ENV + VOP_UNLOCK(afile->vnode); +#else VOP_UNLOCK(afile->vnode, 0); +#endif AFS_GLOCK(); if (code == 0) afile->size = asize; @@ -137,7 +144,7 @@ osi_DisableAtimes(struct vnode *avp) int afs_osi_Read(struct osi_file *afile, int offset, void *aptr, afs_int32 asize) { - unsigned int resid; + size_t resid; afs_int32 code; AFS_STATCNT(osi_Read); @@ -178,7 +185,7 @@ int afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr, afs_int32 asize) { - unsigned int resid; + size_t resid; afs_int32 code; AFS_STATCNT(osi_Write); @@ -188,11 +195,9 @@ afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr, afile->offset = offset; AFS_GUNLOCK(); - VOP_LOCK(afile->vnode, LK_EXCLUSIVE | LK_RETRY); code = - vn_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize, afile->offset, + vn_rdwr(UIO_WRITE, afile->vnode, aptr, asize, afile->offset, AFS_UIOSYS, IO_UNIT, afs_osi_credp, &resid, osi_curproc()); - VOP_UNLOCK(afile->vnode, 0); AFS_GLOCK(); if (code == 0) { @@ -215,7 +220,7 @@ afs_osi_Write(struct osi_file *afile, afs_int32 offset, void *aptr, * bit, but should still be pretty clear. */ int -afs_osi_MapStrategy(int (*aproc) (), struct buf *bp) +afs_osi_MapStrategy(int (*aproc)(struct buf *), struct buf *bp) { afs_int32 returnCode; diff --git a/src/afs/NBSD/osi_groups.c b/src/afs/NBSD/osi_groups.c index 492043a..78b80e7 100644 --- a/src/afs/NBSD/osi_groups.c +++ b/src/afs/NBSD/osi_groups.c @@ -29,43 +29,36 @@ /* * NetBSD has a very flexible and elegant replacement for Unix - * groups KPIs, see KAUTH(9). + * groups KPIs, see kauth(9). * */ -static int -osi_getgroups(kauth_cred_t cred, int ngroups, gid_t * gidset); - +static int osi_getgroups(afs_ucred_t *, int, gid_t *); /* why **? are we returning or reallocating creat? */ -static int -osi_setgroups(struct proc *proc, kauth_cred_t *cred, int ngroups, - gid_t * gidset, int change_parent); +static int osi_setgroups(afs_proc_t *, afs_ucred_t **, int, gid_t *, int); + +int Afs_xsetgroups(afs_proc_t *, const void *, register_t *); int -Afs_xsetgroups(struct proc *p, void *args, int *retval) +Afs_xsetgroups(afs_proc_t *p, const void *args, register_t *retval) { int code = 0; struct vrequest treq; - kauth_cred_t cred = osi_proccred(p); + afs_ucred_t *cred = osi_proccred(p); AFS_STATCNT(afs_xsetgroups); AFS_GLOCK(); - code = afs_InitReq(&treq, (afs_ucred_t *) cred); + code = afs_InitReq(&treq, cred); AFS_GUNLOCK(); if (code) return code; - /* - * XXX Does treq.uid == osi_crgetruid(cred)? - */ -#ifdef AFS_NBSD50_ENV - code = kauth_cred_setgroups(cred, args, retval, osi_crgetruid(cred), UIO_SYSSPACE); -#else - code = kauth_cred_setgroups(cred, args, retval, osi_crgetruid(cred)); -#endif + /* results visible via kauth_cred_getgroups. also does other work */ + code = sys_setgroups(p, args, retval); + /* * Note that if there is a pag already in the new groups we don't * overwrite it with the old pag. @@ -81,9 +74,8 @@ Afs_xsetgroups(struct proc *p, void *args, int *retval) return code; } - int -setpag(struct proc *proc, afs_ucred_t *cred, afs_uint32 pagvalue, +setpag(afs_proc_t *proc, afs_ucred_t **cred, afs_uint32 pagvalue, afs_uint32 * newpag, int change_parent) { gid_t gidset[NGROUPS]; @@ -97,7 +89,7 @@ setpag(struct proc *proc, afs_ucred_t *cred, afs_uint32 pagvalue, if (ngroups + 2 > NGROUPS) { return (E2BIG); } - for (j = ngroups - 1; j >= 0; j--) { + for (j = ngroups - 1; j >= 1; j--) { gidset[j + 2] = gidset[j]; } ngroups += 2; @@ -110,45 +102,41 @@ setpag(struct proc *proc, afs_ucred_t *cred, afs_uint32 pagvalue, static int -osi_getgroups(kauth_cred_t cred, int ngroups, gid_t * gidset) +osi_getgroups(afs_ucred_t *cred, int ngroups, gid_t *gidset) { - int ngrps, savengrps; - struct kauth_cred *cr; - gid_t *gp; - AFS_STATCNT(afs_getgroups); - cr = (struct kauth_cred *) cred; - savengrps = ngrps = MIN(ngroups, kauth_cred_ngroups(cred)); - gp = cred->cr_groups; - while (ngrps--) - *gidset++ = *gp++; - return savengrps; + ngroups = MIN(kauth_cred_ngroups(cred), ngroups); + + kauth_cred_getgroups(cred, gidset, ngroups, UIO_SYSSPACE); + return ngroups; } static int -osi_setgroups(struct proc *proc, kauth_cred_t *cred, int ngroups, +osi_setgroups(afs_proc_t *proc, afs_ucred_t **cred, int ngroups, gid_t * gidset, int change_parent) { - int i; - struct kauth_cred *cr; + int code; + afs_ucred_t *ocred; AFS_STATCNT(afs_setgroups); /* XXX rename statcnt */ if (ngroups > NGROUPS) return EINVAL; - cr = (struct kauth_cred *) *cred; - if (!change_parent) - cr = kauth_cred_copy(cr); + proc_crmod_enter(); + + if (!change_parent) { + ocred = *cred; + *cred = kauth_cred_dup(ocred); + } - for (i = 0; i < ngroups; i++) - cr->cr_groups[i] = gidset[i]; - for (i = ngroups; i < NGROUPS; i++) - cr->cr_groups[i] = NOGROUP; - cr->cr_ngroups = ngroups; + code = kauth_cred_setgroups(*cred, gidset, ngroups, -1, UIO_SYSSPACE); - *cred = cr; - return (0); + if (!change_parent) { + proc_crmod_leave(*cred, ocred, false); + } + + return code; } diff --git a/src/afs/NBSD/osi_kmod.c b/src/afs/NBSD/osi_kmod.c new file mode 100644 index 0000000..e8a3293 --- /dev/null +++ b/src/afs/NBSD/osi_kmod.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2011 Jonathan A. Kollasch + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "afs/param.h" + +#include +#include +#include +#include +#if !defined(AFS_NBSD60_ENV) +#include +#endif +#include +#include +#include +#include +#include + +#include "afs/sysincludes.h" /* Standard vendor system headers */ +#include "afs/afsincludes.h" /* Afs-based standard headers */ + +extern int afs3_syscall(struct lwp *, const void *, register_t *); +extern int afs_xioctl(struct lwp *, const void *, register_t *); +extern int Afs_xsetgroups(struct lwp *, const void *, register_t *); + +#if !defined(AFS_NBSD60_ENV) +extern int sys_lkmnosys(struct lwp *, const void *, register_t *); +#endif + +extern struct vfsops afs_vfsops; + +static const struct sysent openafs_sysent = { + sizeof(struct afs_sysargs)/sizeof(register_t), + sizeof(struct afs_sysargs), + 0, + afs3_syscall, +}; + +static struct sysent old_sysent; +static sy_call_t *old_setgroups; +static sy_call_t *old_ioctl; + +MODULE(MODULE_CLASS_VFS, openafs, NULL); + +static int +openafs_modcmd(modcmd_t cmd, void *arg) +{ + struct sysent *se; + int error; + +#ifndef RUMP + se = sysent; +#else + se = emul_netbsd.e_sysent; +#endif + + switch (cmd) { + case MODULE_CMD_INIT: + error = vfs_attach(&afs_vfsops); + if (error != 0) + break; + old_sysent = se[AFS_SYSCALL]; + old_setgroups = se[SYS_setgroups].sy_call; + old_ioctl = se[SYS_ioctl].sy_call; +#if defined(AFS_NBSD60_ENV) +# ifndef RUMP + if (old_sysent.sy_call == sys_nosys) { +# else + if (true) { +# endif +#else + if (old_sysent.sy_call == sys_lkmnosys) { +#endif +#if defined(AFS_NBSD60_ENV) + kernconfig_lock(); +#endif + se[AFS_SYSCALL] = openafs_sysent; + se[SYS_setgroups].sy_call = Afs_xsetgroups; + se[SYS_ioctl].sy_call = afs_xioctl; +#if defined(AFS_NBSD60_ENV) + kernconfig_unlock(); +#endif + } else { + error = EBUSY; + } + if (error != 0) + break; + break; + case MODULE_CMD_FINI: +#if defined(AFS_NBSD60_ENV) + kernconfig_lock(); +#endif + se[SYS_ioctl].sy_call = old_ioctl; + se[SYS_setgroups].sy_call = old_setgroups; + se[AFS_SYSCALL] = old_sysent; +#if defined(AFS_NBSD60_ENV) + kernconfig_unlock(); +#endif + error = vfs_detach(&afs_vfsops); + if (error != 0) + break; + break; + default: + error = ENOTTY; + break; + } + + return error; +} diff --git a/src/afs/NBSD/osi_machdep.h b/src/afs/NBSD/osi_machdep.h index 5b86606..d80ef35 100644 --- a/src/afs/NBSD/osi_machdep.h +++ b/src/afs/NBSD/osi_machdep.h @@ -9,7 +9,7 @@ /* * - * OpenBSD OSI header file. Extends afs_osi.h. + * NetBSD OSI header file. Extends afs_osi.h. * * afs_osi.h includes this file, which is the only way this file should * be included in a source file. This file can redefine macros declared in @@ -29,15 +29,9 @@ #include #include #endif -#include #include #include -#ifndef AFS_NBSD50_ENV -/* Why are we including the rump debugger? */ -#include "opt_ddb.h" /* Debugger() */ -#endif - #if defined(AFS_NBSD50_ENV) # if !defined(DEF_CADDR_T) typedef char * caddr_t; @@ -45,11 +39,6 @@ typedef char * caddr_t; # endif #endif -#define M_AFSFID (M_TEMP-1) -#define M_AFSBUFHDR (M_TEMP-2) -#define M_AFSBUFFER (M_TEMP-3) -#define M_AFSGENERIC (M_TEMP-4) - /* vfs */ #define osi_vfs mount #define osi_vfs_bsize mnt_stat.f_bsize @@ -61,16 +50,9 @@ typedef char * caddr_t; #endif #define vfs_vnodecovered mnt_vnodecovered #define v_vfsp v_mount -#define VFS_STATFS afs_statvfs - -#ifndef AFS_NBSD50_ENV -/* Defined in sys/syscallargs.h */ -int -sys_ioctl(struct lwp *l, void *v, register_t *retval); -#endif /* vnode */ -#define VN_HOLD(vp) (vref(vp)) +#define VN_HOLD(vp) (vget(vp, 0)) #define VN_RELE(vp) (vrele(vp)) #define osi_vnhold(avc, r) (VN_HOLD(AFSTOV(avc))) @@ -96,107 +78,30 @@ struct afs_sysargs { #define AFS_UIOSYS UIO_SYSSPACE #define AFS_UIOUSER UIO_USERSPACE -/* malloc */ -inline void * afs_osi_Alloc(size_t asize); -inline void * afs_osi_Alloc_NoSleep(size_t asize); -extern void *osi_nbsd_Alloc(size_t asize, int cansleep); -extern void osi_nbsd_Free(void *p, size_t asize); - -#ifdef AFS_KALLOC -#undef AFS_KALLOC -#define AFS_KALLOC(s) (osi_nbsd_Alloc((s), 1 /* cansleep */)) -#endif - -#ifdef AFS_KFREE -#undef AFS_KFREE -#define AFS_KFREE(p, s) (osi_nbsd_Free((p), (s))) -#endif - - /* proc */ typedef struct lwp afs_proc_t; #define osi_curproc() curlwp #define getpid() (osi_curproc())->l_proc->p_pid #define osi_procname(procname, size) strncpy(procname, curproc->p_comm, size) -/* - * XXX I'm exporting the internal definition of kauth_cred_t - * until I work out protocol for switching group buffers. - * Matt. - */ - -#define KAUTH_EXPORT 1 -#if defined(KAUTH_EXPORT) -/* internal type from kern_auth.c */ -#if defined(AFS_NBSD50_ENV) -/* - * Credentials. - * - * A subset of this structure is used in kvm(3) (src/lib/libkvm/kvm_proc.c) - * and should be synchronized with this structure when the update is - * relevant. - */ -struct kauth_cred { - /* - * Ensure that the first part of the credential resides in its own - * cache line. Due to sharing there aren't many kauth_creds in a - * typical system, but the reference counts change very often. - * Keeping it seperate from the rest of the data prevents false - * sharing between CPUs. - */ - u_int cr_refcnt; /* reference count */ -#if COHERENCY_UNIT > 4 - uint8_t cr_pad[COHERENCY_UNIT - 4]; -#endif - uid_t cr_uid; /* user id */ - uid_t cr_euid; /* effective user id */ - uid_t cr_svuid; /* saved effective user id */ - gid_t cr_gid; /* group id */ - gid_t cr_egid; /* effective group id */ - gid_t cr_svgid; /* saved effective group id */ - u_int cr_ngroups; /* number of groups */ - gid_t cr_groups[NGROUPS]; /* group memberships */ - specificdata_reference cr_sd; /* specific data */ -}; -#elif defined(AFS_NBSD40_ENV) -struct kauth_cred { - struct simplelock cr_lock; /* lock on cr_refcnt */ - u_int cr_refcnt; /* reference count */ - uid_t cr_uid; /* user id */ - uid_t cr_euid; /* effective user id */ - uid_t cr_svuid; /* saved effective user id */ - gid_t cr_gid; /* group id */ - gid_t cr_egid; /* effective group id */ - gid_t cr_svgid; /* saved effective group id */ - u_int cr_ngroups; /* number of groups */ - gid_t cr_groups[NGROUPS]; /* group memberships */ -}; -#else -#error TODO: verify kauth_cred structure, if this is still here -#endif /* AFS_NBSD40_ENV */ -#endif /* KAUTH_EXPORT */ - -typedef kauth_cred_t afs_ucred_t; +typedef struct kauth_cred afs_ucred_t; #define osi_curcred() (kauth_cred_get()) #define afs_suser(x) afs_osi_suser(osi_curcred()) #define osi_crgetruid(acred) (kauth_cred_getuid(acred)) #define osi_crgetrgid(acred) (kauth_cred_getgid(acred)) #define osi_crngroups(acred) (kauth_cred_ngroups(acred)) -#define osi_proccred(aproc) (aproc->p_cred) -#define osi_crdup(acred) (kauth_cred_dup(acred)) -#define crref osi_crdup -#define crdup osi_crdup -#define crhold crref +#define osi_proccred(aproc) ((aproc)->l_proc->p_cred) +#define osi_crgroupbyid kauth_cred_group +#define crdup kauth_cred_dup +#define crhold kauth_cred_hold #define crfree kauth_cred_free #define afs_cr_gid osi_crgetrgid #define afs_cr_uid osi_crgetruid -inline gid_t osi_crgroupbyid(afs_ucred_t *acred, int gindex); - /* time */ #define afs_hz hz -#define osi_GetTime(x) microtime(x) +#define osi_GetTime(x) getmicrotime(x) #define osi_Time() time_second /* str */ @@ -215,10 +120,9 @@ inline gid_t osi_crgroupbyid(afs_ucred_t *acred, int gindex); /* This is not always in scope yet */ struct vcache; -extern int afs_nbsd_lookupname(char *fnamep, enum uio_seg segflg, +extern int afs_nbsd_lookupname(const char *fnamep, enum uio_seg segflg, int followlink, struct vnode **compvpp); extern void afs_nbsd_getnewvnode(struct vcache *tvc); -extern int afs_vget(); #undef gop_lookupname #undef gop_lookupname_user @@ -297,12 +201,15 @@ enum vcexcl { NONEXCL, EXCL }; #endif /* ASSEMBLER */ /* vnodes */ -extern int (**afs_vnodeop_p) (); +extern int (**afs_vnodeop_p) __P((void *)); #define vType(vc) AFSTOV(vc)->v_type #define vSetVfsp(vc, vfsp) AFSTOV(vc)->v_mount = (vfsp) #define vSetType(vc, type) AFSTOV(vc)->v_type = (type) #define IsAfsVnode(v) ((v)->v_op == afs_vnodeop_p) #define SetAfsVnode(v) /* nothing; done in getnewvnode() */ +extern int afs_debug; + +#define AFS_USE_NBSD_NAMECACHE 0 #endif /* _OSI_MACHDEP_H_ */ diff --git a/src/afs/NBSD/osi_misc.c b/src/afs/NBSD/osi_misc.c index 7c0b2bc..d89f111 100644 --- a/src/afs/NBSD/osi_misc.c +++ b/src/afs/NBSD/osi_misc.c @@ -71,7 +71,7 @@ afs_osi_suser(void *credp) * may or may not work... */ #ifdef AFS_NBSD50_ENV - code = kauth_authorize_generic(credp, + code = kauth_authorize_generic(credp, KAUTH_GENERIC_ISSUSER, &curlwp->l_ru); #else @@ -82,122 +82,25 @@ afs_osi_suser(void *credp) return (code == 0); } -/* - * Support Alloc_NoSleep. This should propagate back to OBSD. - * Matt. - */ -void * -osi_nbsd_Alloc(size_t asize, int cansleep) -{ - void *p; - int glocked; - - if (cansleep) { - glocked = ISAFS_GLOCK(); - if (glocked) - AFS_GUNLOCK(); - MALLOC(p, void *, asize, M_AFSGENERIC, M_WAITOK); - if (glocked) - AFS_GLOCK(); - } else { - MALLOC(p, void *, asize, M_AFSGENERIC, M_NOWAIT); - } - - return (p); -} - -void -osi_nbsd_Free(void *p, size_t asize) -{ - FREE(p, M_AFSGENERIC); -} - -inline void * -afs_osi_Alloc(size_t asize) { - return (osi_nbsd_Alloc(asize, 1)); -} - -inline void * -afs_osi_Alloc_NoSleep(size_t asize) { - return (osi_nbsd_Alloc(asize, 0)); -} - -inline void -afs_osi_Free(void *buf, size_t asize) { - osi_nbsd_Free(buf, asize); -} - -inline void -afs_osi_FreeStr(char *x) -{ - afs_osi_Free(x, strlen(x) + 1); -} - -/* XXXX OpenBSD avoids space pool, presumably Rees believed the kernel - * allocator did as well or better */ -#ifdef AFS_PRIVATE_OSI_ALLOCSPACES -void -osi_FreeLargeSpace(void *p) -{ - osi_nbsd_Free(p, 0); -} - -/* XXXX OpenBSD avoids space pool, presumably Rees believed the kernel - * allocator did as well or better */ -void -osi_FreeSmallSpace(void *p) -{ - osi_nbsd_Free(p, 0); -} - -void * -osi_AllocLargeSpace(size_t size) -{ - AFS_ASSERT_GLOCK(); - AFS_STATCNT(osi_AllocLargeSpace); - return (osi_nbsd_Alloc(size, 1)); -} - -void * -osi_AllocSmallSpace(size_t size) -{ - AFS_ASSERT_GLOCK(); - AFS_STATCNT(osi_AllocSmallSpace); - return (osi_nbsd_Alloc(size, 1)); -} - -#endif /* AFS_PRIVATE_OSI_ALLOCSPACES */ - int -afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval) - long *retval; - long dev, near_inode, param1, param2, param3, param4; +afs_syscall_icreate(long dev, long near_inode, long param1, long param2, + long param3, long param4, register_t *retval) { return EINVAL; } int -afs_syscall_iopen(dev, inode, usrmod, retval) - long *retval; - int dev, inode, usrmod; +afs_syscall_iopen(int dev, int inode, int usrmod, register_t *retval) { return EINVAL; } int -afs_syscall_iincdec(dev, inode, inode_p1, amount) - int dev, inode, inode_p1, amount; +afs_syscall_iincdec(int dev, int inode, int inode_p1, int amount) { return EINVAL; } -inline gid_t -osi_crgroupbyid(afs_ucred_t *acred, int gindex) -{ - struct kauth_cred *cr = acred; - return (cr->cr_groups[gindex]); -} - /* * just calls kern_time.c:settime() */ diff --git a/src/afs/NBSD/osi_sleep.c b/src/afs/NBSD/osi_sleep.c index b100a10..1f6310a 100644 --- a/src/afs/NBSD/osi_sleep.c +++ b/src/afs/NBSD/osi_sleep.c @@ -48,9 +48,9 @@ such damages. #include "afs/afsincludes.h" /* Afs-based standard headers */ #include "afs/afs_stats.h" /* afs statistics */ +#if !defined(AFS_NBSD50_ENV) static char waitV; - /* cancel osi_Wait */ void afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle) @@ -74,13 +74,13 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok) { int timo, code = 0; struct timeval atv, time_now, endTime; + const struct timeval timezero = { 0, 0 }; AFS_STATCNT(osi_Wait); atv.tv_sec = ams / 1000; atv.tv_usec = (ams % 1000) * 1000; - time_now.tv_sec = time_second; - time_now.tv_usec = 0; + getmicrouptime(&time_now); timeradd(&atv, &time_now, &endTime); if (ahandle) @@ -89,18 +89,19 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok) AFS_GUNLOCK(); do { - - time_now.tv_sec = time_second; - time_now.tv_usec = 0; - timersub(&endTime, &time_now, &atv); - timo = atv.tv_sec * hz + atv.tv_usec * hz / 1000000 + 1; + if (timercmp(&atv, &timezero, <)) + break; + timo = tvtohz(&atv); if (aintok) { code = tsleep(&waitV, PCATCH | PVFS, "afs_W1", timo); - if (code) - code = (code == EWOULDBLOCK) ? 0 : EINTR; - } else - tsleep(&waitV, PVFS, "afs_W2", timo); + } else { + code = tsleep(&waitV, PVFS, "afs_W2", timo); + } + if (code) + code = (code == EWOULDBLOCK) ? 0 : EINTR; + + getmicrouptime(&time_now); /* if we were cancelled, quit now */ if (ahandle && (ahandle->proc == NULL)) { @@ -110,6 +111,7 @@ afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok) } while (timercmp(&time_now, &endTime, <)); AFS_GLOCK(); + return code; } @@ -135,3 +137,203 @@ afs_osi_Wakeup(void *event) wakeup(event); return 1; } +#else +static char waitV; + +void +afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle) +{ + AFS_STATCNT(osi_InitWaitHandle); + achandle->proc = (caddr_t) 0; +} + +/* cancel osi_Wait */ +void +afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle) +{ + caddr_t proc; + + AFS_STATCNT(osi_CancelWait); + proc = achandle->proc; + if (proc == 0) + return; + achandle->proc = (caddr_t) 0; /* so dude can figure out he was signalled */ + afs_osi_Wakeup(&waitV); +} + +/* afs_osi_Wait + * Waits for data on ahandle, or ams ms later. ahandle may be null. + * Returns 0 if timeout and EINTR if signalled. + */ +int +afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int aintok) +{ + int code; + afs_int32 endTime; + + AFS_STATCNT(osi_Wait); + endTime = osi_Time() + (ams / 1000); + if (ahandle) + ahandle->proc = (caddr_t) osi_curproc(); + do { + AFS_ASSERT_GLOCK(); + code = afs_osi_TimedSleep(&waitV, ams, aintok); + + if (code) + break; /* if something happened, quit now */ + /* if we we're cancelled, quit now */ + if (ahandle && (ahandle->proc == (caddr_t) 0)) { + /* we've been signalled */ + break; + } + } while (osi_Time() < endTime); + return code; +} + + + + +typedef struct afs_event { + struct afs_event *next; /* next in hash chain */ + char *event; /* lwp event: an address */ + int refcount; /* Is it in use? */ + int seq; /* Sequence number: this is incremented + * by wakeup calls; wait will not return until + * it changes */ + kcondvar_t cond; /* Currently associated condition variable */ +} afs_event_t; + +#define HASHSIZE 128 +afs_event_t *afs_evhasht[HASHSIZE]; /* Hash table for events */ +#define afs_evhash(event) (afs_uint32) ((((long)event)>>2) & (HASHSIZE-1)); +int afs_evhashcnt = 0; + +/* Get and initialize event structure corresponding to lwp event (i.e. address) + * */ +static afs_event_t * +afs_getevent(char *event) +{ + afs_event_t *evp, *newp = 0; + int hashcode; + + AFS_ASSERT_GLOCK(); + hashcode = afs_evhash(event); + evp = afs_evhasht[hashcode]; + while (evp) { + if (evp->event == event) { + evp->refcount++; + return evp; + } + if (evp->refcount == 0) + newp = evp; + evp = evp->next; + } + if (!newp) { + newp = (afs_event_t *) osi_AllocSmallSpace(sizeof(afs_event_t)); + afs_evhashcnt++; + newp->next = afs_evhasht[hashcode]; + afs_evhasht[hashcode] = newp; + cv_init(&newp->cond, "afsevent"); + newp->seq = 0; + } + newp->event = event; + newp->refcount = 1; + return newp; +} + +/* Release the specified event */ +#define relevent(evp) ((evp)->refcount--) + + +void +afs_osi_Sleep(void *event) +{ + struct afs_event *evp; + int seq; + + evp = afs_getevent(event); + seq = evp->seq; + while (seq == evp->seq) { + AFS_ASSERT_GLOCK(); + cv_wait(&evp->cond, &afs_global_mtx); + } + relevent(evp); +} + +int +afs_osi_SleepSig(void *event) +{ + struct afs_event *evp; + int seq, code = 0; + + evp = afs_getevent(event); + seq = evp->seq; + while (seq == evp->seq) { + AFS_ASSERT_GLOCK(); + code = cv_wait_sig(&evp->cond, &afs_global_mtx); + if (code) { + code = (code == EWOULDBLOCK) ? 0 : EINTR; + break; + } + } + relevent(evp); + return code; +} + +/* afs_osi_TimedSleep + * + * Arguments: + * event - event to sleep on + * ams --- max sleep time in milliseconds + * aintok - 1 if should sleep interruptibly + * + * Returns 0 if timeout and EINTR if signalled. + */ +int +afs_osi_TimedSleep(void *event, afs_int32 ams, int aintok) +{ + int code; + struct afs_event *evp; + int ticks; + + ticks = mstohz(ams); + ticks = ticks ? ticks : 1; + evp = afs_getevent(event); + + AFS_ASSERT_GLOCK(); + if (aintok) { + code = cv_timedwait_sig(&evp->cond, &afs_global_mtx, ticks); + } else { + code = cv_timedwait(&evp->cond, &afs_global_mtx, ticks); + } + + switch (code) { + default: + code = EINTR; + break; + case EWOULDBLOCK: + code = 0; + break; + } + + relevent(evp); + return code; +} + + +int +afs_osi_Wakeup(void *event) +{ + int ret = 1; + struct afs_event *evp; + + evp = afs_getevent(event); + if (evp->refcount > 1) { + evp->seq++; + cv_broadcast(&evp->cond); + ret = 0; + } + relevent(evp); + return 0; +} +#endif diff --git a/src/afs/NBSD/osi_vcache.c b/src/afs/NBSD/osi_vcache.c index 976c875..82034a3 100644 --- a/src/afs/NBSD/osi_vcache.c +++ b/src/afs/NBSD/osi_vcache.c @@ -14,27 +14,32 @@ #include "afsincludes.h" /*AFS-based standard headers */ int -osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) { - *slept = 0; +osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) +{ + int code; - if (!VREFCOUNT_GT(avc,0) - && avc->opens == 0 && (avc->f.states & CUnlinkedDel) == 0) { - /* - * vgone() reclaims the vnode, which calls afs_FlushVCache(), - * then it puts the vnode on the free list. - * If we don't do this we end up with a cleaned vnode that's - * not on the free list. - */ - AFS_GUNLOCK(); - vgone(AFSTOV(avc)); - AFS_GLOCK(); - return 1; + /* Perhaps this function should use vgone() or vrecycle() instead. */ + + if ((afs_debug & AFSDEB_GENERAL) != 0) { + printf("%s enter\n", __func__); + } + + if (osi_VM_FlushVCache(avc, slept) != 0) { + code = 0; + } else { + code = 1; } - return 0; + + if ((afs_debug & AFSDEB_GENERAL) != 0) { + printf("%s exit %d\n", __func__, code); + } + + return code; } struct vcache * -osi_NewVnode(void) { +osi_NewVnode(void) +{ struct vcache *tvc; tvc = (struct vcache *)afs_osi_Alloc(sizeof(struct vcache)); @@ -44,26 +49,27 @@ osi_NewVnode(void) { } void -osi_PrePopulateVCache(struct vcache *avc) { +osi_PrePopulateVCache(struct vcache *avc) +{ memset(avc, 0, sizeof(struct vcache)); } void -osi_AttachVnode(struct vcache *avc, int seq) { +osi_AttachVnode(struct vcache *avc, int seq) +{ ReleaseWriteLock(&afs_xvcache); AFS_GUNLOCK(); afs_nbsd_getnewvnode(avc); /* includes one refcount */ AFS_GLOCK(); ObtainWriteLock(&afs_xvcache,337); -#ifdef AFS_NBSD50_ENV - mutex_init(&avc->rwlock, MUTEX_DEFAULT, IPL_NONE); -#else +#ifndef AFS_NBSD50_ENV lockinit(&avc->rwlock, PINOD, "vcache", 0, 0); #endif } void -osi_PostPopulateVCache(struct vcache *avc) { +osi_PostPopulateVCache(struct vcache *avc) +{ AFSTOV(avc)->v_mount = afs_globalVFS; vSetType(avc, VREG); } diff --git a/src/afs/NBSD/osi_vfsops.c b/src/afs/NBSD/osi_vfsops.c index d257d71..c11d6af 100644 --- a/src/afs/NBSD/osi_vfsops.c +++ b/src/afs/NBSD/osi_vfsops.c @@ -99,35 +99,22 @@ NONINFRINGEMENT. #include "afs/afs_stats.h" /* statistics */ #include +#ifndef AFS_NBSD60_ENV #include +#endif #include +#include -extern unsigned long long afs_debug; +VFS_PROTOS(afs); -#if 0 -/* from /usr/src/sys/kern/vfs_subr.c */ -extern void insmntque(struct vnode *, struct mount *); -#endif -extern int sys_lkmnosys(), afs3_syscall(), afs_xioctl(), Afs_xsetgroups(); +#ifndef AFS_NBSD60_ENV +extern int sys_lkmnosys(struct lwp *, const void *, register_t *); +extern int afs3_syscall(struct lwp *, const void *, register_t *); +extern int afs_xioctl(struct lwp *, const void *, register_t *); +extern int Afs_xsetgroups(struct lwp *, const void *, register_t *); +static int afs_badcall(struct lwp *, const void *, register_t *); static int lkmid = -1; -static int afs_badcall(struct lwp *, void *, register_t *); - -#if 0 -int -newcall(l, v, retval) - struct lwp *l; - void *v; - int *retval; -{ - struct afs_sysargs *uap = v; - - printf("kmod: newcall: %ld %ld %ld %ld\n", - SCARG(uap, syscall), SCARG(uap, parm1), - SCARG(uap, parm2), SCARG(uap, parm3)); - return(0); -} -#endif struct sysent afs_sysent = { 6, sizeof(struct afs_sysargs), @@ -135,20 +122,19 @@ struct sysent afs_sysent = { 6, afs3_syscall}; static struct sysent old_sysent; +static struct sysent old_setgroups; +#endif struct osi_vfs *afs_globalVFS; struct vcache *afs_globalVp; fsid_t afs_dynamic_fsid; -int afs_mount(struct mount *, const char *, void *, - struct nameidata *, struct lwp *); -int afs_start(struct mount *, int, struct lwp *); -int afs_unmount(struct mount *, int, struct lwp *); +int afs_mount(struct mount *, const char *, void *, size_t *); +int afs_start(struct mount *, int); +int afs_unmount(struct mount *, int); int afs_root(struct mount *, struct vnode **); -int afs_quotactl(struct mount *, int, uid_t, void *, struct lwp *); -int afs_statvfs(struct mount *, struct statvfs *, struct lwp *); -int afs_sync(struct mount *, int, kauth_cred_t, struct lwp *); -int afs_vget(struct mount *, ino_t, struct vnode **); +int afs_statvfs(struct mount *, struct statvfs *); +int afs_sync(struct mount *, int, kauth_cred_t); void afs_init(void); void afs_reinit(void); void afs_done(void); @@ -168,40 +154,40 @@ struct vfsops afs_vfsops = { afs_start, afs_unmount, afs_root, - afs_quotactl, + (void *) eopnotsupp, /* vfs_quotactl */ afs_statvfs, afs_sync, - afs_vget, + (void *) eopnotsupp, /* vfs_vget */ (void *) eopnotsupp, /* vfs_fhtovp */ (void *) eopnotsupp, /* vfs_vptofh */ afs_init, afs_reinit, afs_done, - (int (*) (void)) eopnotsupp, /* mountroot */ - (int (*)(struct mount *, struct vnode *, struct timespec *)) eopnotsupp, /* vfs_snapshot */ + (void *) eopnotsupp, /* vfs_mountroot */ + (void *) eopnotsupp, /* vfs_snapshot */ vfs_stdextattrctl, #ifdef AFS_NBSD50_ENV - (int (*)(struct mount *, int)) eopnotsupp, /* vfs_suspendctl */ - (int (*)(struct mount *)) eopnotsupp, /* vfs_renamelock_enter */ - (void *) eopnotsupp, /* vfs_renamelock_exit */ - (int (*)(struct vnode*, int)) eopnotsupp, /* vfs_fsync */ + (void *) eopnotsupp, /* vfs_suspendctl */ + genfs_renamelock_enter, /* vfs_renamelock_enter */ + genfs_renamelock_exit, /* vfs_renamelock_exit */ + (void *) eopnotsupp, /* vfs_fsync */ #endif afs_vnodeopv_descs, - 0, /* vfs_refcount */ + 0, /* vfs_refcount */ { NULL, NULL }, }; -VFS_ATTACH(afs_vfsops); - int -afs_nbsd_lookupname(char *fnamep, enum uio_seg segflg, int followlink, +afs_nbsd_lookupname(const char *fnamep, enum uio_seg segflg, int followlink, struct vnode **compvpp) { struct nameidata nd; int niflag; int error; - afs_warn("afs_nbsd_lookupname enter (%s)\n", fnamep); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + afs_warn("afs_nbsd_lookupname enter (%s)\n", fnamep); + } /* * Lookup pathname "fnamep", returning leaf in *compvpp. segflg says @@ -213,32 +199,28 @@ afs_nbsd_lookupname(char *fnamep, enum uio_seg segflg, int followlink, * NBSD50 seems to have stopped caring about the curproc of things. * mattjsm */ -#ifdef AFS_NBSD50_ENV - NDINIT(&nd, LOOKUP, niflag, segflg, fnamep); +#if defined(AFS_NBSD60_ENV) + struct pathbuf *ipb = NULL; + ipb = pathbuf_create(fnamep); + NDINIT(&nd, LOOKUP, niflag, ipb); +#elif defined(AFS_NBSD50_ENV) + NDINIT(&nd, LOOKUP, niflag, segflg, fnamep); #else NDINIT(&nd, LOOKUP, niflag, segflg, fnamep, osi_curproc()); #endif - if ((error = namei(&nd))) - return error; + if ((error = namei(&nd))) { + goto out; + } *compvpp = nd.ni_vp; +out: +#if defined(AFS_NBSD60_ENV) + pathbuf_destroy(ipb); +#endif return error; } int -afs_quotactl(struct mount *mp, int cmd, uid_t uid, - void *arg, struct lwp *l) -{ - return EOPNOTSUPP; -} - -int -afs_sysctl() -{ - return EOPNOTSUPP; -} - -int -afs_start(struct mount *mp, int flags, struct lwp *l) +afs_start(struct mount *mp, int flags) { return (0); /* nothing to do? */ } @@ -250,20 +232,22 @@ void afs_done(void) int afs_mount(struct mount *mp, const char *path, void *data, - struct nameidata *ndp, struct lwp *l) + size_t *dlen) { /* ndp contains the mounted-from device. Just ignore it. * we also don't care about our proc struct. */ - u_int size; + size_t size; AFS_STATCNT(afs_mount); - afs_warn("afs_mount enter\n"); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + afs_warn("afs_mount enter\n"); + } if (mp->mnt_flag & MNT_UPDATE) return EINVAL; - if (afs_globalVFS) { + if (afs_globalVFS != NULL) { /* Don't allow remounts */ return EBUSY; } @@ -279,33 +263,30 @@ afs_mount(struct mount *mp, const char *path, void *data, mp->mnt_stat.f_bsize = 8192; mp->mnt_stat.f_frsize = 8192; mp->mnt_stat.f_iosize = 8192; -#if 0 - mp->osi_vfs_fsid.val[0] = AFS_VFSMAGIC; /* magic */ - mp->osi_vfs_fsid.val[1] = (int)AFS_VFSFSID; -#else + mp->mnt_fs_bshift = DEV_BSHIFT; + mp->mnt_dev_bshift = DEV_BSHIFT; vfs_getnewfsid(mp); afs_dynamic_fsid = mp->mnt_stat.f_fsidx; -#endif (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); - bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); - bzero(mp->mnt_stat.f_mntfromname, MNAMELEN); + memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size); + memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN); strcpy(mp->mnt_stat.f_mntfromname, "AFS"); /* null terminated string "AFS" will fit, just leave it be. */ strcpy(mp->mnt_stat.f_fstypename, AFS_MOUNT_AFS); AFS_GUNLOCK(); - (void)afs_statvfs(mp, &mp->mnt_stat, l); + (void)afs_statvfs(mp, &mp->mnt_stat); - afs_warn("afs_mount exit\n"); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + afs_warn("afs_mount exit\n"); + } return 0; } int -afs_unmount(struct mount *mp, int mntflags, struct lwp *l) +afs_unmount(struct mount *mp, int mntflags) { - extern int sys_ioctl(), sys_setgroups(); - AFS_STATCNT(afs_unmount); #ifdef AFS_DISCON_ENV give_up_cbs(); @@ -319,90 +300,117 @@ afs_unmount(struct mount *mp, int mntflags, struct lwp *l) afs_globalVp = NULL; vflush(mp, NULLVP, 0); /* don't support forced */ - mp->mnt_data = NULL; AFS_GLOCK(); - afs_globalVFS = 0; + afs_globalVFS = NULL; afs_cold_shutdown = 1; afs_shutdown(); /* XXX */ AFS_GUNLOCK(); - printf - ("AFS unmounted--use `/sbin/modunload -i %d' to unload before restarting AFS\n", - lkmid); + mp->mnt_data = NULL; + + printf("AFS unmounted.\n"); return 0; } +#ifndef AFS_NBSD60_ENV static int -afs_badcall(struct lwp *l, void *xx, register_t * yy) +afs_badcall(struct lwp *l, const void *xx, register_t *yy) { return ENOSYS; } +#endif int afs_root(struct mount *mp, struct vnode **vpp) { struct vrequest treq; struct vcache *tvp; - int code, glocked; + struct vcache *gvp; + int code; AFS_STATCNT(afs_root); - glocked = ISAFS_GLOCK(); - afs_warn("afs_root enter, glocked==%d\n", glocked); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + int glocked = ISAFS_GLOCK(); + afs_warn("afs_root enter, glocked==%d\n", glocked); + } AFS_GLOCK(); - afs_warn("glocked\n"); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + afs_warn("afs_root: glocked\n"); + } - if (!(code = afs_InitReq(&treq, osi_curcred())) - && !(code = afs_CheckInit())) { + tvp = NULL; +tryagain: + if (afs_globalVp && (afs_globalVp->f.states & CStatd)) { + tvp = afs_globalVp; + code = 0; + } else { + if (afs_globalVp) { + gvp = afs_globalVp; + afs_globalVp = NULL; + afs_PutVCache(gvp); + } - afs_warn("afs_root: initReq && CheckInit: code==%d\n", code); + if (!(code = afs_InitReq(&treq, osi_curcred())) + && !(code = afs_CheckInit())) { + tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL); - tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL); - afs_warn("afs_root: GetVCache: tvp==%lx\n", tvp); - if (tvp) { - /* There is really no reason to over-hold this bugger--it's held - * by the root filesystem reference. */ - if (afs_globalVp != tvp) { -#ifdef AFS_DONT_OVERHOLD_GLOBALVP - if (afs_globalVp) - AFS_RELE(AFSTOV(afs_globalVp)); -#endif + if (tvp) { + if (afs_globalVp) { + + afs_PutVCache(tvp); + tvp = NULL; + goto tryagain; + } afs_globalVp = tvp; - VREF(AFSTOV(afs_globalVp)); - } -/* v_flag no longer exists... mattjsm */ -#ifdef AFS_NBSD50_ENV - AFSTOV(tvp)->v_vflag |= VV_ROOT; -#else - AFSTOV(tvp)->v_flag |= VROOT; -#endif + } else + code = ENOENT; + } + } + if (tvp) { + struct vnode *vp = AFSTOV(tvp); + AFS_GUNLOCK(); + vref(vp); + if (code != 0) { + vrele(vp); + return code; + } + if (!VOP_ISLOCKED(*vpp)) + code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + AFS_GLOCK(); + if (!afs_globalVp || !(afs_globalVp->f.states & CStatd) || + tvp != afs_globalVp) { + vput(vp); + afs_PutVCache(tvp); + tvp = NULL; + goto tryagain; + } + if (code != 0) + goto tryagain; + vp->v_vflag |= VV_ROOT; + if (afs_globalVFS != mp) afs_globalVFS = mp; - *vpp = AFSTOV(tvp); - } else - code = ENOENT; + *vpp = vp; } AFS_GUNLOCK(); - afs_warn("afs_root: gunlocked\n"); - - if (!code) { - if (!VOP_ISLOCKED(*vpp)) - vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY); /* return it locked */ + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + afs_warn("afs_root exit\n"); } - afs_warn("afs_root exit\n"); - return code; } int -afs_statvfs(struct mount *mp, struct statvfs *abp, struct lwp *l) +afs_statvfs(struct mount *mp, struct statvfs *abp) { AFS_STATCNT(afs_statfs); - afs_warn("afs_statvfs enter\n"); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + afs_warn("afs_statvfs enter\n"); + } /* thank you, NetBSD */ copy_statvfs_info(abp, mp); @@ -427,7 +435,7 @@ afs_statvfs(struct mount *mp, struct statvfs *abp, struct lwp *l) } int -afs_sync(struct mount *mp, int waitfor, kauth_cred_t cred, struct lwp *l) +afs_sync(struct mount *mp, int waitfor, kauth_cred_t cred) { AFS_STATCNT(afs_sync); #if defined(AFS_DISCON_ENV) @@ -437,14 +445,8 @@ afs_sync(struct mount *mp, int waitfor, kauth_cred_t cred, struct lwp *l) return 0; } -int -afs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) -{ - return (EOPNOTSUPP); -} - void -afs_init() +afs_init(void) { osi_Init(); return; @@ -456,6 +458,7 @@ afs_reinit(void) return; } +#ifndef AFS_NBSD60_ENV /* LKM */ /* @@ -463,62 +466,35 @@ afs_reinit(void) */ MOD_VFS("afs", -1, &afs_vfsops); -#if 0 -static char afsgenmem[] = "afsgenmem"; -static char afsfidmem[] = "afsfidmem"; -static char afsbhdrmem[] = "afsbhdrmem"; -static char afsbfrmem[] = "afsbfrmem"; -#endif - -int +static int afs_vfs_load(struct lkm_table *lkmtp, int cmd) { -#if 0 - extern char *memname[]; - - if (memname[M_AFSGENERIC] == NULL) - memname[M_AFSGENERIC] = afsgenmem; - if (memname[M_AFSFID] == NULL) - memname[M_AFSFID] = afsfidmem; - if (memname[M_AFSBUFHDR] == NULL) - memname[M_AFSBUFHDR] = afsbhdrmem; - if (memname[M_AFSBUFFER] == NULL) - memname[M_AFSBUFFER] = afsbfrmem; -#endif - lkmid = lkmtp->id; - if (sysent[AFS_SYSCALL].sy_call != sys_nosys) { - printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n", - AFS_SYSCALL); - /* return EEXIST; */ + lkmid = lkmtp->id; + if (sysent[AFS_SYSCALL].sy_call != sys_lkmnosys) { + printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n", + AFS_SYSCALL); + /* return EEXIST; */ } old_sysent = sysent[AFS_SYSCALL]; sysent[AFS_SYSCALL] = afs_sysent; + old_setgroups = sysent[SYS_setgroups]; + sysent[SYS_setgroups].sy_call = Afs_xsetgroups; +#if NOTYET + old_ioctl = sysent[SYS_ioctl]; + sysent[SYS_ioctl].sy_call = afs_xioctl; +#endif - printf("OpenAFS lkm loaded id: %d\n", lkmid); + aprint_verbose("OpenAFS loaded\n"); return (0); } -int +static int afs_vfs_unload(struct lkm_table *lktmp, int cmd) { -#if 0 - extern char *memname[]; -#endif - if (afs_globalVp) return EBUSY; -#if 0 - if (memname[M_AFSGENERIC] == afsgenmem) - memname[M_AFSGENERIC] = NULL; - if (memname[M_AFSFID] == afsfidmem) - memname[M_AFSFID] = NULL; - if (memname[M_AFSBUFHDR] == afsbhdrmem) - memname[M_AFSBUFHDR] = NULL; - if (memname[M_AFSBUFFER] == afsbfrmem) - memname[M_AFSBUFFER] = NULL; -#endif if (sysent[AFS_SYSCALL].sy_call != afs_sysent.sy_call) { printf("LKM afs_vfs_load(): AFS3 syscall %d already used\n", @@ -527,11 +503,17 @@ afs_vfs_unload(struct lkm_table *lktmp, int cmd) } sysent[AFS_SYSCALL] = old_sysent; + sysent[SYS_setgroups] = old_setgroups; +#if NOTYET + sysent[SYS_ioctl] = old_ioctl; +#endif printf("OpenAFS unloaded\n"); return (0); } +int libafs_lkmentry(struct lkm_table *, int, int); + int libafs_lkmentry(struct lkm_table *lkmtp, int cmd, int ver) { @@ -543,9 +525,6 @@ libafs_lkmentry(struct lkm_table *lkmtp, int cmd, int ver) } } -#if DEBUG - afs_debug = AFSDEB_VNLAYER; -#endif - DISPATCH(lkmtp, cmd, ver, afs_vfs_load, afs_vfs_unload, lkm_nofunc); } +#endif diff --git a/src/afs/NBSD/osi_vm.c b/src/afs/NBSD/osi_vm.c index 39f8921..5cc2beb 100644 --- a/src/afs/NBSD/osi_vm.c +++ b/src/afs/NBSD/osi_vm.c @@ -24,9 +24,6 @@ #include "afs/sysincludes.h" /* Standard vendor system headers */ #include "afs/afsincludes.h" /* Afs-based standard headers */ #include "afs/afs_stats.h" /* statistics */ -/* #include */ -#include -#include /* Try to discard pages, in order to recycle a vcache entry. * @@ -47,6 +44,26 @@ int osi_VM_FlushVCache(struct vcache *avc, int *slept) { + struct vnode *vp = AFSTOV(avc); + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("%s enter\n", __func__); + } + + if (vp == NULL) { + printf("%s NULL vp\n", __func__); + return 0; + } + + AFS_GUNLOCK(); + cache_purge(vp); + vflushbuf(vp, 1); + AFS_GLOCK(); + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("%s exit\n", __func__); + } + return 0; } @@ -58,6 +75,22 @@ osi_VM_FlushVCache(struct vcache *avc, int *slept) void osi_VM_StoreAllSegments(struct vcache *avc) { + struct vnode *vp; + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("%s enter\n", __func__); + } + + ReleaseWriteLock(&avc->lock); + AFS_GUNLOCK(); + vp = AFSTOV(avc); + mutex_enter(&vp->v_interlock); + VOP_PUTPAGES(vp, 0, 0, PGO_ALLPAGES|PGO_CLEANIT|PGO_SYNCIO); + AFS_GLOCK(); + ObtainWriteLock(&avc->lock, 94); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("%s exit\n", __func__); + } } /* Try to invalidate pages, for "fs flush" or "fs flushv"; or @@ -72,6 +105,17 @@ osi_VM_StoreAllSegments(struct vcache *avc) void osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync) { + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("%s enter\n", __func__); + } + + ReleaseWriteLock(&avc->lock); + osi_VM_FlushVCache(avc, NULL); + ObtainWriteLock(&avc->lock, 59); + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("%s exit\n", __func__); + } } /* Purge VM for a file when its callback is revoked. @@ -81,6 +125,23 @@ osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync) void osi_VM_FlushPages(struct vcache *avc, afs_ucred_t *credp) { + struct vnode *vp = AFSTOV(avc); + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("%s enter\n", __func__); + } + + if (!vp) { + printf("%s NULL vp\n", __func__); + return; + } + + cache_purge(vp); + vinvalbuf(vp, 0, credp, curlwp, false, 1); + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("%s exit\n", __func__); + } } /* Purge pages beyond end-of-file, when truncating a file. @@ -90,6 +151,17 @@ osi_VM_FlushPages(struct vcache *avc, afs_ucred_t *credp) * it only works on Solaris. */ void -osi_VM_Truncate(struct vcache *avc, int alen, afs_ucred_t *acred) +osi_VM_Truncate(struct vcache *avc, voff_t alen, afs_ucred_t *acred) { + struct vnode *vp = AFSTOV(avc); + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("%s enter\n", __func__); + } + + vtruncbuf(vp, alen, false, 0); + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("%s exit\n", __func__); + } } diff --git a/src/afs/NBSD/osi_vnodeops.c b/src/afs/NBSD/osi_vnodeops.c index c7c8729..4c172aa 100644 --- a/src/afs/NBSD/osi_vnodeops.c +++ b/src/afs/NBSD/osi_vnodeops.c @@ -107,13 +107,10 @@ NONINFRINGEMENT. #include #include - #include "afs/afs_cbqueue.h" #include "afs/nfsclient.h" #include "afs/afs_osidnlc.h" -#define M_AFSNODE (M_TEMP-1) /* XXX */ - int afs_nbsd_lookup(void *); int afs_nbsd_create(void *); int afs_nbsd_mknod(void *); @@ -125,7 +122,6 @@ int afs_nbsd_setattr(void *); int afs_nbsd_read(void *); int afs_nbsd_write(void *); int afs_nbsd_ioctl(void *); -int afs_nbsd_select(void *); int afs_nbsd_fsync(void *); int afs_nbsd_remove(void *); int afs_nbsd_link(void *); @@ -146,33 +142,17 @@ int afs_nbsd_islocked(void *); int afs_nbsd_pathconf(void *); int afs_nbsd_advlock(void *); -#if LATER -int afs_nbsd_getpages(void*); -#endif +int afs_debug; /* - * Implement: - * vop_getpages (VM) - * vop_putpages (VM) - * - * Someday: - * vop_mmap_desc (mmap'd IO) - * * Skip: * vop_*xtattr * - * Unknown: - * vop_fcntl - * */ -#define afs_nbsd_opnotsupp \ - ((int (*) __P((void *)))eopnotsupp) -#define afs_nbsd_reallocblks afs_nbsd_opnotsupp - /* Global vfs data structures for AFS. */ int (**afs_vnodeop_p) __P((void *)); -struct vnodeopv_entry_desc afs_vnodeop_entries[] = { +const struct vnodeopv_entry_desc afs_vnodeop_entries[] = { {&vop_default_desc, vn_default_error}, {&vop_lookup_desc, afs_nbsd_lookup}, /* lookup */ {&vop_create_desc, afs_nbsd_create}, /* create */ @@ -184,10 +164,17 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = { {&vop_setattr_desc, afs_nbsd_setattr}, /* setattr */ {&vop_read_desc, afs_nbsd_read}, /* read */ {&vop_write_desc, afs_nbsd_write}, /* write */ +#if NOTYET {&vop_ioctl_desc, afs_nbsd_ioctl}, /* XXX ioctl */ - {&vop_poll_desc, afs_nbsd_select}, /* select */ +#else + {&vop_ioctl_desc, genfs_enoioctl}, /* ioctl */ +#endif + {&vop_fcntl_desc, genfs_fcntl}, /* fcntl */ + {&vop_poll_desc, genfs_poll}, /* poll */ {&vop_kqfilter_desc, genfs_kqfilter }, /* kqfilter */ + {&vop_mmap_desc, genfs_mmap}, /* mmap */ {&vop_fsync_desc, afs_nbsd_fsync}, /* fsync */ + {&vop_seek_desc, genfs_seek}, /* seek */ {&vop_remove_desc, afs_nbsd_remove}, /* remove */ {&vop_link_desc, afs_nbsd_link}, /* link */ {&vop_rename_desc, afs_nbsd_rename}, /* rename */ @@ -210,25 +197,54 @@ struct vnodeopv_entry_desc afs_vnodeop_entries[] = { #if 0 {&vop_reallocblks_desc, afs_nbsd_reallocblks}, /* reallocblks */ #endif - {&vop_bwrite_desc, vn_bwrite}, /* bwrite */ -#if LATER - { &vop_getpages_desc, ffs_getpages }, /* getpages */ - { &vop_putpages_desc, genfs_putpages }, /* putpages */ -#endif - {(struct vnodeop_desc *)NULL, (int (*)__P((void *)))NULL} + {&vop_bwrite_desc, vn_bwrite}, /* bwrite */ + {&vop_getpages_desc, genfs_getpages}, /* getpages */ + {&vop_putpages_desc, genfs_putpages}, /* putpages */ + { NULL, NULL} }; -struct vnodeopv_desc afs_vnodeop_opv_desc = +const struct vnodeopv_desc afs_vnodeop_opv_desc = { &afs_vnodeop_p, afs_vnodeop_entries }; -#define GETNAME() \ - struct componentname *cnp = ap->a_cnp; \ - char *name; \ - name = PNBUF_GET(); \ - bcopy(cnp->cn_nameptr, name, cnp->cn_namelen); \ - name[cnp->cn_namelen] = '\0' +static void +afs_nbsd_gop_size(struct vnode *vp, off_t size, off_t *eobp, int flags) +{ + + *eobp = MAX(size, vp->v_size); +} -#define DROPNAME() PNBUF_PUT(name) -#define DROPCNP PNBUF_PUT +static int +afs_nbsd_gop_alloc(struct vnode *vp, off_t off, off_t len, int flags, + kauth_cred_t cred) +{ + + return (0); +} + +static const struct genfs_ops afs_genfsops = { + .gop_size = afs_nbsd_gop_size, + .gop_alloc = afs_nbsd_gop_alloc, + .gop_write = genfs_gop_write, +}; + +extern void cpu_Debugger(void); + +static char * +cnstrdup(const struct componentname *cnp) +{ + char *string; + + string = PNBUF_GET(); + memcpy(string, cnp->cn_nameptr, cnp->cn_namelen); + string[cnp->cn_namelen] = '\0'; + + return string; +} + +static void +cnstrfree(char *string) +{ + PNBUF_PUT(string); +} /* toss "stale" pages by shrinking the vnode uobj to a 0-length * region (see uvm_vnp_setsize in uvm_vnode.c) */ @@ -255,30 +271,32 @@ struct vnodeopv_desc afs_vnodeop_opv_desc = void afs_nbsd_getnewvnode(struct vcache *tvc) { - while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &tvc->v)) { + struct nbvdata *vd; + + KASSERT(AFSTOV(tvc) == NULL); + while (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &AFSTOV(tvc))) { /* no vnodes available, force an alloc (limits be damned)! */ + printf("afs: upping desiredvnodes\n"); desiredvnodes++; } - printf("afs_nbsd_getnewvnode: vp %p refs %d\n", tvc->v, - tvc->v->v_usecount); + + vd = kmem_zalloc(sizeof(*vd), KM_SLEEP); #ifdef AFS_NBSD50_ENV - mutex_enter(&tvc->v->v_interlock); + mutex_enter(&AFSTOV(tvc)->v_interlock); #else - simple_lock(&tvc->v->v_interlock); -#endif - tvc->v->v_data = (void *)tvc; -#if 0 - tvc->v->v_usecount = 1; /* !locked, and vref w/v_usecount < 1 panics */ + simple_lock(&AFSTOV(tvc)->v_interlock); #endif + vd->afsvc = tvc; + AFSTOV(tvc)->v_data = vd; + genfs_node_init(AFSTOV(tvc), &afs_genfsops); #ifdef AFS_NBSD50_ENV - mutex_exit(&tvc->v->v_interlock); + mutex_exit(&AFSTOV(tvc)->v_interlock); #else - simple_unlock(&tvc->v->v_interlock); + simple_unlock(&AFSTOV(tvc)->v_interlock); #endif + uvm_vnp_setsize(AFSTOV(tvc), 0); } -unsigned long long afs_debug; - int afs_nbsd_lookup(void *v) { @@ -288,101 +306,92 @@ afs_nbsd_lookup(void *v) * struct vnode **a_vpp; * struct componentname *a_cnp; * } */ *ap = v; - int code; + struct vnode *dvp, *vp; struct vcache *vcp; - struct vnode *vp, *dvp; - int flags = ap->a_cnp->cn_flags; - int lockparent; /* 1 => lockparent flag is set */ - - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_lookup enter ap %p\n", ap); + struct componentname *cnp; + char *name; + int code; - GETNAME(); - lockparent = flags & LOCKPARENT; - if (ap->a_dvp->v_type != VDIR) { - *ap->a_vpp = NULL; - DROPNAME(); - return ENOTDIR; + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_lookup a_cnp->cn_nameptr %s cred %p a_dvp %p\n", + ap->a_cnp->cn_nameptr, ap->a_cnp->cn_cred, ap->a_dvp); + } else { + KASSERT(VOP_ISLOCKED(ap->a_dvp)); } + dvp = ap->a_dvp; -/* -* v_flag was broke up into 3 separate flags. v_vflag is the -* substitute when referencing V_ROOT (which was also renamed) -* -* mattjsm -*/ -#ifdef AFS_NBSD50_ENV - if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_vflag & VV_ROOT)) -#else - if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT)) + vp = *ap->a_vpp = NULL; + cnp = ap->a_cnp; + +#if AFS_USE_NBSD_NAMECACHE + code = cache_lookup(dvp, ap->a_vpp, cnp); + if (code >= 0) + goto out; #endif - printf("nbsd_lookup dvp %p flags %x name %s v_usecnt %d\n", dvp, flags, - name, dvp->v_usecount); + + code = 0; + + if (dvp->v_type != VDIR) { + code = ENOTDIR; + goto out; + } + + name = cnstrdup(cnp); AFS_GLOCK(); code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred); AFS_GUNLOCK(); - if (code) { - if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) - && (flags & ISLASTCN) && code == ENOENT) - code = EJUSTRETURN; - if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) + cnstrfree(name); name = NULL; + + if (code == ENOENT + && (cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) + && (cnp->cn_flags & ISLASTCN)) { + *ap->a_vpp = NULL; + code = EJUSTRETURN; +#if !defined(AFS_NBSD60_ENV) cnp->cn_flags |= SAVENAME; - DROPNAME(); - *ap->a_vpp = NULL; - return (code); +#endif + goto out; } - vp = AFSTOV(vcp); /* always get a node if no error */ - /* - * The parent directory comes in locked. We unlock it on return - * unless the caller wants it left locked. - * we also always return the vnode locked. - */ - - if (vp == dvp) { - /* they're the same; afs_lookup() already ref'ed the leaf. - * It came in locked, so we don't need to ref OR lock it */ - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_lookup: ref'ed %p as .\n", dvp); - } else { - if (!lockparent || !(flags & ISLASTCN)) { - VOP_UNLOCK(dvp, 0); /* done with parent. */ - } - - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_lookup dvp %p flags %x name %s v_usecnt %d\n", - dvp, flags, name, dvp->v_usecount); - - /* XXXX hacked here, recheck OBSD and bundled--NBSD has - * removed PDIRUNLOCK, so we must at least accommodate that - * change. M.*/ - if (!VOP_ISLOCKED(vp)) { - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_lookup: omitting to always return child locked\n"); - /* vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); *//* always return the child locked */ - } else { - if (afs_debug & AFSDEB_VNLAYER) - printf("lookup: vp %p is locked\n", vp); + if (code == 0) { + vp = *ap->a_vpp = AFSTOV(vcp); + if (cnp->cn_flags & ISDOTDOT) { +#if defined(AFS_NBSD60_ENV) + VOP_UNLOCK(dvp); +#else + VOP_UNLOCK(dvp, 0); +#endif + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); + } else if (vp == dvp) { + vref(dvp); + } else { + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); } - if (afs_debug & AFSDEB_VNLAYER) - printf("locked ret %p from lookup\n", vp); } - *ap->a_vpp = vp; - if (((cnp->cn_nameiop == RENAME && (flags & ISLASTCN)) - || (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)))) - cnp->cn_flags |= SAVENAME; +#if AFS_USE_NBSD_NAMECACHE + if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE) { + cache_enter(dvp, *ap->a_vpp, cnp); + } +#endif - DROPNAME(); + out: +#if 0 #ifdef AFS_NBSD50_ENV - if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_vflag & VV_ROOT)) + if ((afs_debug & AFSDEB_VNLAYER) != 0 && (dvp->v_vflag & VV_ROOT) != 0) #else - if (afs_debug & AFSDEB_VNLAYER && !(dvp->v_flag & VROOT)) + if ((afs_debug & AFSDEB_VNLAYER) != 0 && (dvp->v_flag & VROOT) != 0) +#endif #endif - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_lookup done ap %p dvp %p cnt %d\n", ap, dvp, - dvp->v_usecount); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_lookup done dvp %p cnt %d\n", dvp, dvp->v_usecount); + } + + if (code == 0 && afs_debug == 0) { + KASSERT(VOP_ISLOCKED(*ap->a_vpp)); + } + return (code); } @@ -398,22 +407,28 @@ afs_nbsd_create(void *v) int code = 0; struct vcache *vcp; struct vnode *dvp = ap->a_dvp; - GETNAME(); - - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount); + struct componentname *cnp = ap->a_cnp; + char *name; + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + /* printf("nbsd_create dvp %p cnt %d\n", dvp, dvp->v_usecount); */ + printf("nbsd_create a_cnp->cn_nameptr %s cred %p a_dvp %p\n", + ap->a_cnp->cn_nameptr, ap->a_cnp->cn_cred, ap->a_dvp); + /* printf("name: %d %s\n", ap->a_cnp->cn_namelen, name); */ + } /* vnode layer handles excl/nonexcl */ + name = cnstrdup(cnp); AFS_GLOCK(); code = afs_create(VTOAFS(dvp), name, ap->a_vap, NONEXCL, ap->a_vap->va_mode, &vcp, cnp->cn_cred); AFS_GUNLOCK(); + cnstrfree(name); if (code) { VOP_ABORTOP(dvp, cnp); vput(dvp); - DROPNAME(); return (code); } @@ -421,14 +436,17 @@ afs_nbsd_create(void *v) *ap->a_vpp = AFSTOV(vcp); vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY); } else - *ap->a_vpp = 0; + *ap->a_vpp = NULL; - if ((cnp->cn_flags & SAVESTART) == 0) - DROPCNP(cnp); +#if !defined(AFS_NBSD60_ENV) + if (code || (cnp->cn_flags & SAVESTART) == 0) { + PNBUF_PUT(cnp->cn_pnbuf); + } +#endif vput(dvp); - DROPNAME(); - if (afs_debug & AFSDEB_VNLAYER) + if ((afs_debug & AFSDEB_VNLAYER) != 0) { printf("nbsd_create done dvp %p cnt %d\n", dvp, dvp->v_usecount); + } return code; } @@ -442,15 +460,21 @@ afs_nbsd_mknod(void *v) * struct vattr *a_vap; * } */ *ap = v; - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_mknod: enter ap %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_mknod: enter %p dvp %p\n", ap, ap->a_dvp); + } - DROPCNP(ap->a_cnp); + +#if !defined(AFS_NBSD60_ENV) + PNBUF_PUT(ap->a_cnp->cn_pnbuf); +#endif vput(ap->a_dvp); - return (ENODEV); - if (afs_debug & AFSDEB_VNLAYER) + if ((afs_debug & AFSDEB_VNLAYER) != 0) { printf("nbsd_mknod: exit ap %p\n", ap); + } + + return (ENODEV); } int @@ -466,8 +490,9 @@ afs_nbsd_open(void *v) struct vnode *vp = ap->a_vp; struct vcache *vc = VTOAFS(vp); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_open: enter vp %p vc %p\n", vp, vc); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_open: enter %p vp %p vc %p\n", ap, ap->a_vp, vc); + } AFS_GLOCK(); code = afs_open(&vc, ap->a_mode, ap->a_cred); @@ -477,8 +502,11 @@ afs_nbsd_open(void *v) #endif AFS_GUNLOCK(); - if (afs_debug & AFSDEB_VNLAYER) + uvm_vnp_setsize(ap->a_vp, VTOAFS(ap->a_vp)->f.m.Length); + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { printf("nbsd_open: exit vp %p vc %p\n", vp, vc); + } return (code); } @@ -496,15 +524,17 @@ afs_nbsd_close(void *v) struct vnode *vp = ap->a_vp; struct vcache *vc = VTOAFS(vp); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_close: enter vp %p vc %p\n", vp, vc); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_close: enter %p vp %p vc %p\n", ap, ap->a_vp, vc); + } AFS_GLOCK(); code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred); AFS_GUNLOCK(); - if (afs_debug & AFSDEB_VNLAYER) + if ((afs_debug & AFSDEB_VNLAYER) != 0) { printf("nbsd_close: exit vp %p vc %p\n", vp, vc); + } return (code); } @@ -522,15 +552,17 @@ afs_nbsd_access(void *v) struct vnode *vp = ap->a_vp; struct vcache *vc = VTOAFS(vp); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_access: enter vp %p vc %p mode %d\n", vp, vc, ap->a_mode); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_access: enter %p vp %p vc %p mode %d\n", ap, ap->a_vp, vc, ap->a_mode); + } AFS_GLOCK(); code = afs_access(VTOAFS(ap->a_vp), ap->a_mode, ap->a_cred); AFS_GUNLOCK(); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_access: exit vp %p vc %p mode %d\n", vp, vc, ap->a_mode); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_access: exit vp %p vc %p mode %d\n", vp, vc, ap->a_mode); + } return (code); } @@ -548,17 +580,19 @@ afs_nbsd_getattr(void *v) struct vnode *vp = ap->a_vp; struct vcache *vc = VTOAFS(vp); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_getattr: enter vp %p vc %p acred %p\n", vp, vc, - ap->a_cred); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_getattr: enter %p vp %p vc %p acred %p\n", + ap, ap->a_vp, vc, ap->a_cred); + } AFS_GLOCK(); code = afs_getattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred); AFS_GUNLOCK(); - if (afs_debug & AFSDEB_VNLAYER) + if ((afs_debug & AFSDEB_VNLAYER) != 0) { printf("nbsd_getattr: exit vp %p vc %p acred %p\n", vp, vc, ap->a_cred); + } return (code); } @@ -574,15 +608,17 @@ afs_nbsd_setattr(void *v) * } */ *ap = v; int code; - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_setattr: enter %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_setattr: enter %p vp %p\n", ap, ap->a_vp); + } AFS_GLOCK(); code = afs_setattr(VTOAFS(ap->a_vp), ap->a_vap, ap->a_cred); AFS_GUNLOCK(); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_setattr: exit %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_setattr: exit %p\n", ap); + } return (code); } @@ -598,15 +634,22 @@ afs_nbsd_read(void *v) * } */ *ap = v; int code; - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_read enter %p", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_read enter %p vp %p\n", ap, ap->a_vp); + } + +#if 0 + if (ap->a_uio->uio_offset > ap->a_vp->v_size) { + return 0; } +#endif AFS_GLOCK(); code = afs_read(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred, 0); AFS_GUNLOCK(); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_read exit %p", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_read exit %p\n", ap); + } return (code); } @@ -622,22 +665,23 @@ afs_nbsd_write(void *v) * } */ *ap = v; int code; - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_write enter %p", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_write enter %p vp %p\n", ap, ap->a_vp); + } -#if 1 - /* all pages are really "stale?" */ - VNP_UNCACHE(ap->a_vp); -#else - (void)uvm_vnp_uncache(ap->a_vp); /* toss stale pages */ -#endif AFS_GLOCK(); + /* osi_FlushPages(VTOAFS(ap->a_vp), ap->a_cred); */ code = afs_write(VTOAFS(ap->a_vp), ap->a_uio, ap->a_ioflag, ap->a_cred, 0); AFS_GUNLOCK(); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_write exit %p", ap); + if (ap->a_vp->v_size < ap->a_uio->uio_offset) { + uvm_vnp_setsize(ap->a_vp, ap->a_uio->uio_offset); + } + + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_write exit %p\n", ap); + } return (code); } @@ -655,8 +699,9 @@ afs_nbsd_ioctl(void *v) * } */ *ap = v; int code; - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_ioctl: enter %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_ioctl: enter %p vp %p\n", ap, ap->a_vp); + } /* in case we ever get in here... */ @@ -672,19 +717,14 @@ afs_nbsd_ioctl(void *v) code = ENOTTY; AFS_GUNLOCK(); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_ioctl: exit %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_ioctl: exit %p\n", ap); + } return (code); } int -afs_nbsd_select(void *v) -{ - return 1; -} - -int afs_nbsd_fsync(void *v) { struct vop_fsync_args /* { @@ -697,7 +737,7 @@ afs_nbsd_fsync(void *v) int code, wait; if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_fsync: enter %p\n", ap); + printf("nbsd_fsync: enter %p vp %p\n", ap, ap->a_vp); wait = (ap->a_flags & FSYNC_WAIT) != 0; @@ -723,21 +763,22 @@ afs_nbsd_remove(void *v) int code; struct vnode *vp = ap->a_vp; struct vnode *dvp = ap->a_dvp; + struct componentname *cnp = ap->a_cnp; + char *name; if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_remove: enter %p\n", ap); + printf("nbsd_remove: enter %p vp %p\n", ap, ap->a_vp); - GETNAME(); + name = cnstrdup(cnp); AFS_GLOCK(); code = afs_remove(VTOAFS(dvp), name, cnp->cn_cred); AFS_GUNLOCK(); + cnstrfree(name); name = NULL; if (dvp == vp) vrele(vp); else vput(vp); vput(dvp); - DROPCNP(cnp); - DROPNAME(); if (afs_debug & AFSDEB_VNLAYER) printf("nbsd_remove: exit %p\n", ap); @@ -756,11 +797,12 @@ afs_nbsd_link(void *v) int code; struct vnode *dvp = ap->a_dvp; struct vnode *vp = ap->a_vp; + struct componentname *cnp = ap->a_cnp; + char *name; if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_link: enter %p\n", ap); + printf("nbsd_link: enter %p vp %p\n", ap, ap->a_vp); - GETNAME(); if (dvp->v_mount != vp->v_mount) { VOP_ABORTOP(vp, cnp); code = EXDEV; @@ -771,21 +813,28 @@ afs_nbsd_link(void *v) code = EISDIR; goto out; } - if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY))) { + if (dvp != vp) { + if ((code = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY))) { VOP_ABORTOP(dvp, cnp); goto out; + } } + name = cnstrdup(cnp); AFS_GLOCK(); code = afs_link(VTOAFS(vp), VTOAFS(dvp), name, cnp->cn_cred); AFS_GUNLOCK(); - DROPCNP(cnp); - if (dvp != vp) + cnstrfree(name); name = NULL; + if (dvp != vp) { +#if defined(AFS_NBSD60_ENV) + VOP_UNLOCK(vp); +#else VOP_UNLOCK(vp, 0); +#endif + } out: vput(dvp); - DROPNAME(); if (afs_debug & AFSDEB_VNLAYER) printf("nbsd_link: exit %p\n", ap); @@ -857,10 +906,14 @@ afs_nbsd_rename(void *v) vrele(fvp); fcnp->cn_flags &= ~MODMASK; fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; + fcnp->cn_nameiop = DELETE; +#if !defined(AFS_NBSD60_ENV) if ((fcnp->cn_flags & SAVESTART) == 0) panic("afs_rename: lost from startdir"); - fcnp->cn_nameiop = DELETE; (void)relookup(fdvp, &fvp, fcnp); +#else + (void)relookup(fdvp, &fvp, fcnp, 0); +#endif code = VOP_REMOVE(fdvp, fvp, fcnp); goto out; } @@ -868,24 +921,16 @@ afs_nbsd_rename(void *v) if ((code = vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY))) goto abortit; - /* XXX GETNAME() ? */ - MALLOC(fname, char *, fcnp->cn_namelen + 1, M_TEMP, M_WAITOK); - bcopy(fcnp->cn_nameptr, fname, fcnp->cn_namelen); - fname[fcnp->cn_namelen] = '\0'; - MALLOC(tname, char *, tcnp->cn_namelen + 1, M_TEMP, M_WAITOK); - bcopy(tcnp->cn_nameptr, tname, tcnp->cn_namelen); - tname[tcnp->cn_namelen] = '\0'; + fname = cnstrdup(fcnp); + tname = cnstrdup(tcnp); AFS_GLOCK(); /* XXX use "from" or "to" creds? NFS uses "to" creds */ - code = - afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, - tcnp->cn_cred); + code = afs_rename(VTOAFS(fdvp), fname, VTOAFS(tdvp), tname, tcnp->cn_cred); AFS_GUNLOCK(); - VOP_UNLOCK(fvp, 0); - FREE(fname, M_TEMP); - FREE(tname, M_TEMP); + cnstrfree(fname); fname = NULL; + cnstrfree(tname); tname = NULL; if (code) goto abortit; /* XXX */ if (tdvp == tvp) @@ -895,7 +940,7 @@ afs_nbsd_rename(void *v) if (tvp) vput(tvp); vrele(fdvp); - vrele(fvp); + vput(fvp); out: if (afs_debug & AFSDEB_VNLAYER) @@ -915,33 +960,42 @@ afs_nbsd_mkdir(void *v) * } */ *ap = v; struct vnode *dvp = ap->a_dvp; struct vattr *vap = ap->a_vap; - int code; + struct componentname *cnp = ap->a_cnp; struct vcache *vcp; + int code; + char *name; + if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_mkdir: enter %p\n", ap); + printf("nbsd_mkdir: enter %p dvp %p\n", ap, ap->a_dvp); - GETNAME(); +#if !defined(AFS_NBSD60_ENV) #ifdef DIAGNOSTIC if ((cnp->cn_flags & HASBUF) == 0) panic("afs_nbsd_mkdir: no name"); #endif +#endif + + name = cnstrdup(cnp); AFS_GLOCK(); code = afs_mkdir(VTOAFS(dvp), name, vap, &vcp, cnp->cn_cred); AFS_GUNLOCK(); + cnstrfree(name); name = NULL; if (code) { VOP_ABORTOP(dvp, cnp); vput(dvp); - DROPNAME(); goto out; } if (vcp) { *ap->a_vpp = AFSTOV(vcp); vn_lock(AFSTOV(vcp), LK_EXCLUSIVE | LK_RETRY); } else - *ap->a_vpp = 0; - DROPCNP(cnp); - DROPNAME(); + *ap->a_vpp = NULL; +#if !defined(AFS_NBSD60_ENV) + if (code || (cnp->cn_flags & SAVESTART) == 0) { + PNBUF_PUT(cnp->cn_pnbuf); + } +#endif vput(dvp); out: @@ -962,24 +1016,32 @@ afs_nbsd_rmdir(void *v) int code; struct vnode *vp = ap->a_vp; struct vnode *dvp = ap->a_dvp; + struct componentname *cnp = ap->a_cnp; + char *name; + if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_rmdir: enter %p", ap); + printf("nbsd_rmdir: enter %p vp %p\n", ap, ap->a_vp); - GETNAME(); if (dvp == vp) { vrele(dvp); vput(vp); - DROPCNP(cnp); - DROPNAME(); code = EINVAL; goto out; } + name = cnstrdup(cnp); AFS_GLOCK(); code = afs_rmdir(VTOAFS(dvp), name, cnp->cn_cred); AFS_GUNLOCK(); - DROPNAME(); + cnstrfree(name); name = NULL; + +#if AFS_USE_NBSD_NAMECACHE + if (code == 0) { + cache_purge(vp); + } +#endif + vput(dvp); vput(vp); @@ -1001,99 +1063,42 @@ afs_nbsd_symlink(void *v) * char *a_target; * } */ *ap = v; struct vnode *dvp = ap->a_dvp; + struct vnode *nvp = NULL; + struct vcache *vcp; + struct componentname *cnp = ap->a_cnp; int code; + char *name; /* NFS ignores a_vpp; so do we. */ if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_symlink: enter %p\n", ap); + printf("nbsd_symlink: enter %p dvp %p\n", ap, ap->a_dvp); - GETNAME(); + name = cnstrdup(cnp); AFS_GLOCK(); code = afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred); + if (code == 0) { + code = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred); + if (code == 0) { + nvp = AFSTOV(vcp); + vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY); + } + } AFS_GUNLOCK(); - DROPCNP(cnp); - DROPNAME(); - vput(dvp); - - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_symlink: exit %p\n", ap); + cnstrfree(name); name = NULL; +#if !defined(AFS_NBSD60_ENV) + if (code || (cnp->cn_flags & SAVESTART) == 0) { + PNBUF_PUT(cnp->cn_pnbuf); + } +#endif - return (code); -} + *(ap->a_vpp) = nvp; -int -nbsd_fake_readdir(struct vnode *vp, struct vcache *vc, struct uio *auio, - kauth_cred_t acred, int *a_eofflag, int *a_ncookies, - u_long **a_cookies) -{ - static int ino = 2; - afs_int32 code, maxb; - struct dirent *dp; - maxb = auio->uio_resid; + vput(dvp); if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_fake_readdir: enter vp %p vc %p acred %p auio %p " - "uio_offset %d uio_resid %d\n", - vp, vc, acred, auio, (int) auio->uio_offset, - (int) auio->uio_resid); - - /* 1. simply returning 0 had good behavior (/afs is empty) */ - -/* -(gdb) p *auio -$5 = {uio_iov = 0xcbd0ec90, uio_iovcnt = 1, uio_offset = 0, uio_resid = 4096, - uio_rw = UIO_READ, uio_vmspace = 0xcbe8beec} -*/ - /* ok. we don't know about cookies, so since auio->uio_resid is 4096, - * what we can legitimately do is move as many appropriately aligned - * NetBSD dirent records into uio_iov[0] as will fit in the total size - * of 4KB. We do not need to zero-fill anything. This does not - * terminate the directly listing. If we return 0, VFS will re-enter - * nbsd_readdir to continue reading--to termiate the iteration, we must - * return a non-zero value from nbsd_readdir. VOP_READDIR(9) appears to - * suggest that enumeration is terminated by setting a_eofflag = 1, - * but as noted there this -can- only be done if VFS passed a value for - * a_eofflag--apparently, this is to do with NFS. Setting the eof is - * correct but insufficient. */ - - /* 2. next, let's move ONE entry in by hand--due to termination - * rules, this will actually create file_1 .. file_99 and many - * unecessary nbsd_readdir invocations. The solution to this is to - * make proper use of auio->uio_offset and auio->uio_resid, together - * when accounting bytes moved each invocation, allowing VFS to - * invoke nbsd_readdir at successive offsets until we have consumed - * all entries in all chunks of the vnode being read--setting a_eofflag - * when this is done. - */ - - /* this isn't thread safe--we would in fact use incoming offset - * to select the offset of the next AFS dirent, read it, then take - * its values for (modulo volume) inode number and name */ - if (auio->uio_offset == 0) - ino = 2; - - dp = (struct dirent *) kmem_zalloc(sizeof(struct dirent), KM_SLEEP); - dp->d_ino = ino; - dp->d_type = DT_REG; - sprintf(dp->d_name, "file_%d", ino); - dp->d_namlen = strlen(dp->d_name); - dp->d_reclen = _DIRENT_SIZE(dp); /* comp reclen from d_namlen and align */ - printf("nbsd_fake_readdir: add dirent %s\n", dp->d_name); - code = uiomove(dp, dp->d_reclen, auio); - if (code) - printf("nbsd_fake_readdir: uiomove FAILED\n"); - kmem_free(dp, sizeof(struct dirent)); - ++ino; - - /* terminate enumeration */ - if (!code) - if (ino > 100) { - code = EINVAL; - if(a_eofflag) - *a_eofflag = 1; - } + printf("nbsd_symlink: exit %p\n", ap); return (code); } @@ -1114,8 +1119,8 @@ afs_nbsd_readdir(void *v) struct vcache *vc = VTOAFS(vp); if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_readdir: enter vp %p vc %p acred %p auio %p\n", vp, vc, - ap->a_cred, ap->a_uio); + printf("nbsd_readdir: enter %p vp %p vc %p acred %p auio %p\n", ap, + vp, vc, ap->a_cred, ap->a_uio); AFS_GLOCK(); #ifdef AFS_HAVE_COOKIES @@ -1147,7 +1152,7 @@ afs_nbsd_readlink(void *v) int code; if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_readlink: enter %p\n", ap); + printf("nbsd_readlink: enter %p vp %p\n", ap, ap->a_vp); AFS_GLOCK(); code = afs_readlink(VTOAFS(ap->a_vp), ap->a_uio, ap->a_cred); @@ -1174,21 +1179,23 @@ afs_nbsd_inactive(void *v) AFS_STATCNT(afs_inactive); if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_inactive: enter %p\n", ap); + printf("nbsd_inactive: enter %p vp %p\n", ap, ap->a_vp); if (prtactive && vp->v_usecount != 0) vprint("afs_nbsd_inactive: pushing active", vp); if (!haveGlock) AFS_GLOCK(); - afs_InactiveVCache(vc, 0); /* decrs ref counts */ + afs_InactiveVCache(vc, NULL); /* decrs ref counts */ if (!haveGlock) AFS_GUNLOCK(); -#ifdef AFS_NBSD50_ENV - mutex_init(&vc->rwlock, MUTEX_DEFAULT, IPL_NONE); + *ap->a_recycle = (vc->f.states & CUnlinked) != 0; + +#if defined(AFS_NBSD60_ENV) + VOP_UNLOCK(vp); #else - lockinit(&vc->rwlock, PINOD, "vcache", 0, 0); + VOP_UNLOCK(vp, 0); #endif if (afs_debug & AFSDEB_VNLAYER) @@ -1209,41 +1216,53 @@ afs_nbsd_reclaim(void *v) int haveGlock = ISAFS_GLOCK(); int haveVlock = CheckLock(&afs_xvcache); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_reclaim: enter %p\n", ap); - -#if 0 - printf("reclaim usecount %d\n", vp->v_usecount); - /* OK, there are no internal vrefCounts, so there shouldn't - * be any more refs here. */ - vp->v_data = NULL; /* remove from vnode */ - avc->v = NULL; /* also drop the ptr to vnode */ - - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_reclaim: exit %p\n", ap); + if (afs_debug & AFSDEB_VNLAYER) + printf("nbsd_reclaim: enter %p vp %p\n", ap, vp); - return (0); -#else if (!haveGlock) AFS_GLOCK(); if (!haveVlock) ObtainWriteLock(&afs_xvcache, 901); -#ifndef AFS_DISCON_ENV - code = afs_FlushVCache(avc, &slept); /* tosses our stuff from vnode */ -#else /* reclaim the vnode and the in-memory vcache, but keep the on-disk vcache */ code = afs_FlushVCache(avc, &slept); + +#if 1 + if (avc->f.states & CVInit) { + avc->f.states &= ~CVInit; + afs_osi_Wakeup(&avc->f.states); + } #endif + if (!haveVlock) - ReleaseWriteLock(&afs_xvcache); + ReleaseWriteLock(&afs_xvcache); if (!haveGlock) - AFS_GUNLOCK(); + AFS_GUNLOCK(); + + if (vp->v_tag != VT_AFS) { + vprint("afs reclaim", vp); + } + KASSERT(vp->v_tag == VT_AFS); + + if (vp->v_data != NULL) { + genfs_node_destroy(vp); + kmem_free(vp->v_data, sizeof(struct nbvdata)); + vp->v_data = NULL; /* remove from vnode */ + avc->v = NULL; /* also drop the ptr to vnode */ + } else { + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + vprint("reclaim", vp); + } + } + +#if AFS_USE_NBSD_NAMECACHE + cache_purge(vp); +#endif - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_reclaim: exit %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_reclaim: exit %p\n", ap); + } return code; -#endif /* 0 */ } int @@ -1255,16 +1274,18 @@ afs_nbsd_lock(void *v) * struct lwp *a_l; * } */ *ap = v; int code; - struct vnode *vp = ap->a_vp; - int flags = ap->a_flags; - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_lock: enter vp %p flags %d\n", vp, flags); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_lock: enter %p vp %p\n", ap, ap->a_vp); + } + + KASSERT(VTOAFS(ap->a_vp) != NULL); code = genfs_lock(v); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_lock: exit vp %p flags %d\n\n", vp, flags); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_lock: exit %p\n", ap); + } return (code); } @@ -1278,16 +1299,18 @@ afs_nbsd_unlock(void *v) * struct lwp *a_l; * } */ *ap = v; int code; - struct vnode *vp = ap->a_vp; - int flags = ap->a_flags; - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_unlock: enter vp %p flags %d\n", vp, flags); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_unlock: enter %p vp %p\n", ap, ap->a_vp); + } + + KASSERT(VTOAFS(ap->a_vp) != NULL); code = genfs_unlock(v); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_unlock: exit vp %p flags %d\n", vp, flags); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_unlock: exit %p\n", ap); + } return (code); } @@ -1300,15 +1323,16 @@ afs_nbsd_islocked(void *v) * } */ *ap = v; int code; - struct vnode *vp = ap->a_vp; - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_islocked: enter vp %p flags %d\n", vp); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_islocked: enter %p vp %p\n", ap, ap->a_vp); + } code = genfs_islocked(v); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_islocked: exit vp %p flags %d\n", vp); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_islocked: exit %p\n", ap); + } return (code); } @@ -1324,27 +1348,27 @@ afs_nbsd_bmap(void *v) * daddr_t *a_bnp; * int *a_runp; * } */ *ap = v; - struct vcache *vcp = VTOAFS(ap->a_vp); AFS_STATCNT(afs_bmap); if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_bmap: enter %p\n", ap); + printf("nbsd_bmap: enter %p vp %p\n", ap, ap->a_vp); - /* borrowed from DARWIN--why notyet? */ if (ap->a_bnp) - *ap->a_bnp = ap->a_bn * (PAGE_SIZE / DEV_BSIZE); + *ap->a_bnp = ap->a_bn; if (ap->a_vpp) *ap->a_vpp = ap->a_vp; if (ap->a_runp != NULL) - *ap->a_runp = 0; + *ap->a_runp = 1024 * 1024; /* XXX */ #ifdef notyet if (ap->a_runb != NULL) *ap->a_runb = 0; #endif +#if 0 if (afs_debug & AFSDEB_VNLAYER) printf("nbsd_bmap: exit %p\n", ap); +#endif return (0); } @@ -1355,54 +1379,21 @@ afs_nbsd_strategy(void *v) struct vop_strategy_args /* { * struct buf *a_bp; * } */ *ap = v; - struct buf *abp = ap->a_bp; - struct uio tuio; - struct iovec tiovec[1]; - struct vcache *tvc = VTOAFS(abp->b_vp); - afs_ucred_t credp = osi_curcred(); - long len = abp->b_bcount; int code; AFS_STATCNT(afs_strategy); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_strategy: enter %p\n", ap); - - tuio.afsio_iov = tiovec; - tuio.afsio_iovcnt = 1; - tuio.afsio_resid = len; -/* - * b_un was removed in NBSD50...there's no true substitute for the - * b_addr that was in it, but b_blkno is the closest. - * mattjsm - */ -#ifdef AFS_NBSD50_ENV - tiovec[0].iov_base = abp->b_blkno; -#else - tiovec[0].iov_base = abp->b_un.b_addr; -#endif - tiovec[0].iov_len = len; - UIO_SETUP_SYSSPACE(&tuio); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_strategy: enter %p vp %p\n", ap, ap->a_vp); + } AFS_GLOCK(); - if ((abp->b_flags & B_READ) == B_READ) { - code = afs_rdwr(tvc, &tuio, UIO_READ, 0, credp); - if (code == 0 && tuio.afsio_resid > 0) -#ifdef AFS_NBSD50_ENV - bzero(abp->b_blkno + len - tuio.afsio_resid, -#else - bzero(abp->b_un.b_addr + len - tuio.afsio_resid, -#endif - tuio.afsio_resid); - } else - code = afs_rdwr(tvc, &tuio, UIO_WRITE, 0, credp); + code = afs_ustrategy(ap->a_bp, osi_curcred()); AFS_GUNLOCK(); - ReleaseWriteLock(&tvc->lock); - AFS_RELE(AFSTOV(tvc)); - - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_strategy: exit %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_strategy: exit %p vp %p\n", ap, ap->a_vp); + } return (code); } @@ -1417,10 +1408,12 @@ afs_nbsd_print(void *v) struct vcache *vc = VTOAFS(ap->a_vp); printf("tag %d, fid: %d.%x.%x.%x, ", vp->v_tag, vc->f.fid.Cell, - (int)vc->f.fid.Fid.Volume, (int)vc->f.fid.Fid.Vnode, - (int)vc->f.fid.Fid.Unique); + vc->f.fid.Fid.Volume, vc->f.fid.Fid.Vnode, + vc->f.fid.Fid.Unique); #ifdef AFS_NBSD50_ENV - mutex_owned(&vc->rwlock); +#if defined(DDB) && defined(LOCKDEBUG) + lockdebug_lock_print(&vc->rwlock, printf); +#endif #else lockmgr_printinfo(&vc->rwlock); #endif @@ -1443,8 +1436,9 @@ afs_nbsd_pathconf(void *v) AFS_STATCNT(afs_cntl); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_pathconf: enter %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_pathconf: enter %p vp %p\n", ap, ap->a_vp); + } switch (ap->a_name) { case _PC_LINK_MAX: @@ -1472,8 +1466,9 @@ afs_nbsd_pathconf(void *v) } out: - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_pathconf: exit %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_pathconf: exit %p\n", ap); + } return (0); } @@ -1497,17 +1492,18 @@ afs_nbsd_advlock(void *v) * } */ *ap = v; int code; - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_pathconf: enter %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_pathconf: enter %p vp %p\n", ap, ap->a_vp); + } AFS_GLOCK(); - code = - afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(), - (int)ap->a_id); + code = afs_lockctl(VTOAFS(ap->a_vp), ap->a_fl, ap->a_op, osi_curcred(), + (uintptr_t)ap->a_id); AFS_GUNLOCK(); - if (afs_debug & AFSDEB_VNLAYER) - printf("nbsd_pathconf: exit %p\n", ap); + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + printf("nbsd_pathconf: exit %p\n", ap); + } return (code); } diff --git a/src/afs/VNOPS/afs_vnop_read.c b/src/afs/VNOPS/afs_vnop_read.c index 765e89a..d4244a4 100644 --- a/src/afs/VNOPS/afs_vnop_read.c +++ b/src/afs/VNOPS/afs_vnop_read.c @@ -598,10 +598,15 @@ afs_UFSReadUIO(afs_dcache_id_t *cacheId, struct uio *tuiop) VOP_UNLOCK(tfile->vnode, 0, curthread); AFS_GLOCK(); #elif defined(AFS_NBSD_ENV) + tuiop->uio_rw = UIO_READ; AFS_GUNLOCK(); VOP_LOCK(tfile->vnode, LK_EXCLUSIVE); code = VOP_READ(tfile->vnode, tuiop, 0, afs_osi_credp); +# if defined(AFS_NBSD60_ENV) + VOP_UNLOCK(tfile->vnode); +# else VOP_UNLOCK(tfile->vnode, 0); +# endif AFS_GLOCK(); #elif defined(AFS_XBSD_ENV) AFS_GUNLOCK(); diff --git a/src/afs/VNOPS/afs_vnop_readdir.c b/src/afs/VNOPS/afs_vnop_readdir.c index b394239..12a049d 100644 --- a/src/afs/VNOPS/afs_vnop_readdir.c +++ b/src/afs/VNOPS/afs_vnop_readdir.c @@ -29,14 +29,11 @@ #include "afs/afs_cbqueue.h" #include "afs/nfsclient.h" #include "afs/afs_osidnlc.h" -#if defined(AFS_NBSD40_ENV) -#include /* direct_pool */ -#endif #if defined(AFS_HPUX1122_ENV) #define DIRPAD 7 #elif defined(AFS_NBSD40_ENV) -#define DIRPAD 4 +#define DIRPAD 7 #else #define DIRPAD 3 #endif @@ -217,6 +214,10 @@ int afs_rd_stash_i = 0; #ifdef AFS_SUN5_ENV #define DIRSIZ_LEN(len) ((10 + (len) + 1 + (NBPW-1)) & ~(NBPW-1)) #else +#ifdef AFS_NBSD40_ENV +#define DIRSIZ_LEN(len) \ + ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((len)+1 + 7) & ~7)) +#else #ifdef AFS_DIRENT #define DIRSIZ_LEN(len) \ ((sizeof (struct dirent) - (MAXNAMLEN+1)) + (((len)+1 + 3) &~ 3)) @@ -231,6 +232,7 @@ int afs_rd_stash_i = 0; ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((len)+1 + 3) &~ 3)) #endif /* AFS_SGI_ENV */ #endif /* AFS_DIRENT */ +#endif /* AFS_NBSD40_ENV */ #endif /* AFS_SUN5_ENV */ #endif /* AFS_SUN56_ENV */ #endif /* AFS_HPUX100_ENV */ @@ -503,12 +505,7 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio, #if defined(AFS_NBSD40_ENV) { struct dirent *dp; - dp = (struct dirent *) -#if defined(AFS_NBSD50_ENV) - osi_AllocLargeSpace(AFS_LRALLOCSIZ); -#else - pool_get(&ufs_direct_pool, PR_WAITOK); -#endif + dp = osi_AllocLargeSpace(sizeof(struct dirent)); memset(dp, 0, sizeof(struct dirent)); dp->d_ino = (Volume << 16) + ntohl(Vnode); FIXUPSTUPIDINODE(dp->d_ino); @@ -516,14 +513,12 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio, dp->d_type = afs_readdir_type(vc, de); strcpy(dp->d_name, de->name); dp->d_reclen = _DIRENT_SIZE(dp) /* rlen */; - afs_warn("afs_readdir_move %s type %d slen %d rlen %d act. rlen %d\n", - dp->d_name, dp->d_type, slen, rlen, _DIRENT_SIZE(dp)); - AFS_UIOMOVE((char*) dp, sizeof(struct dirent), UIO_READ, auio, code); -#if defined(AFS_NBSD50_ENV) + if ((afs_debug & AFSDEB_VNLAYER) != 0) { + afs_warn("%s: %s type %d slen %d rlen %d act. rlen %zu\n", __func__, + dp->d_name, dp->d_type, slen, rlen, _DIRENT_SIZE(dp)); + } + AFS_UIOMOVE(dp, dp->d_reclen, UIO_READ, auio, code); osi_FreeLargeSpace((char *)dp); -#else - pool_put(&ufs_direct_pool, dp); -#endif } #else AFS_UIOMOVE((char *) &sdirEntry, sizeof(sdirEntry), UIO_READ, auio, code); @@ -538,6 +533,7 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio, #endif AFS_MOVE_LOCK(); #endif /* AFS_SGI_ENV */ +#if !defined(AFS_NBSD_ENV) /* pad out the difference between rlen and slen... */ if (DIRSIZ_LEN(slen) < rlen) { AFS_MOVE_UNLOCK(); @@ -550,6 +546,7 @@ afs_readdir_move(struct DirEntry *de, struct vcache *vc, struct uio *auio, } AFS_MOVE_LOCK(); } +#endif #endif /* AFS_SUN5_ENV */ #endif /* AFS_SGI53_ENV */ return (code); @@ -781,13 +778,13 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred) } #else code = afs_readdir_move(ode, avc, auio, o_slen, -#if defined(AFS_SUN5_ENV) +#if defined(AFS_SUN5_ENV) || defined(AFS_NBSD_ENV) len, origOffset); #else AFS_UIO_RESID(auio), origOffset); #endif #endif /* AFS_HPUX_ENV */ -#if !defined(AFS_SUN5_ENV) +#if !defined(AFS_SUN5_ENV) && !defined(AFS_NBSD_ENV) AFS_UIO_SETRESID(auio, 0); #endif } else { @@ -855,7 +852,9 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred) /* this next line used to be AFSVFS40 or AIX 3.1, but is * really generic */ AFS_UIO_SETOFFSET(auio, origOffset); +#if !defined(AFS_NBSD_ENV) AFS_UIO_SETRESID(auio, 0); +#endif } else { /* trouble, can't give anything to the user! */ /* even though he has given us a buffer, * even though we have something to give us, diff --git a/src/afs/VNOPS/afs_vnop_strategy.c b/src/afs/VNOPS/afs_vnop_strategy.c index 44532f2..f5cf404 100644 --- a/src/afs/VNOPS/afs_vnop_strategy.c +++ b/src/afs/VNOPS/afs_vnop_strategy.c @@ -95,7 +95,9 @@ int afs_ustrategy(struct buf *abp) tuio.afsio_fmode = 0; #endif tuio.afsio_resid = abp->b_bcount; -#if defined(AFS_XBSD_ENV) +#if defined(AFS_NBSD40_ENV) + tiovec[0].iov_base = abp->b_data; +#elif defined(AFS_XBSD_ENV) tiovec[0].iov_base = abp->b_saveaddr; #else tiovec[0].iov_base = abp->b_un.b_addr; @@ -110,7 +112,10 @@ int afs_ustrategy(struct buf *abp) #endif if (code == 0) { if (tuio.afsio_resid > 0) -#if defined(AFS_XBSD_ENV) +#if defined(AFS_NBSD40_ENV) + memset((char *)abp->b_data + (uintptr_t)abp->b_bcount - tuio.afsio_resid, 0, + tuio.afsio_resid); +#elif defined(AFS_XBSD_ENV) memset(abp->b_saveaddr + abp->b_bcount - tuio.afsio_resid, 0, tuio.afsio_resid); #else @@ -172,7 +177,9 @@ int afs_ustrategy(struct buf *abp) len = MIN(len, tvc->f.m.Length - dbtob(abp->b_blkno)); #endif tuio.afsio_resid = len; -#if defined(AFS_XBSD_ENV) +#if defined(AFS_NBSD40_ENV) + tiovec[0].iov_base = abp->b_data; +#elif defined(AFS_XBSD_ENV) tiovec[0].iov_base = abp->b_saveaddr; #else tiovec[0].iov_base = abp->b_un.b_addr; @@ -202,6 +209,9 @@ int afs_ustrategy(struct buf *abp) (*abp->b_iodone)(abp); #elif defined(AFS_FBSD_ENV) biodone(&abp->b_io); +#elif defined(AFS_NBSD40_ENV) + abp->b_resid = tuio.uio_resid; + biodone(abp); #elif defined(AFS_XBSD_ENV) biodone(abp); #elif !defined(AFS_SUN5_ENV) diff --git a/src/afs/VNOPS/afs_vnop_write.c b/src/afs/VNOPS/afs_vnop_write.c index 3420e1f..58f09d5 100644 --- a/src/afs/VNOPS/afs_vnop_write.c +++ b/src/afs/VNOPS/afs_vnop_write.c @@ -174,7 +174,11 @@ afs_UFSWriteUIO(struct vcache *avc, afs_dcache_id_t *inode, struct uio *tuiop) AFS_GUNLOCK(); VOP_LOCK(tfile->vnode, LK_EXCLUSIVE); code = VOP_WRITE(tfile->vnode, tuiop, 0, afs_osi_credp); +#if defined(AFS_NBSD60_ENV) + VOP_UNLOCK(tfile->vnode); +#else VOP_UNLOCK(tfile->vnode, 0); +#endif AFS_GLOCK(); #elif defined(AFS_XBSD_ENV) AFS_GUNLOCK(); diff --git a/src/afs/afs.h b/src/afs/afs.h index 7787e17..a911269 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -743,6 +743,13 @@ extern afs_int32 vmPageHog; /* counter for # of vnodes which are page hogs. */ #if defined(AFS_DARWIN80_ENV) #define VTOAFS(v) ((struct vcache *)vnode_fsnode((v))) #define AFSTOV(vc) ((vc)->v) +#elif defined(AFS_NBSD40_ENV) +struct nbvdata { + struct genfs_node gfsn; + struct vcache *afsvc; +}; +#define VTOAFS(v) ((((struct nbvdata *)((v)->v_data)))->afsvc) +#define AFSTOV(vc) ((vc)->v) #elif defined(AFS_XBSD_ENV) || defined(AFS_DARWIN_ENV) || (defined(AFS_LINUX22_ENV) && !defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE)) #define VTOAFS(v) ((struct vcache *)(v)->v_data) #define AFSTOV(vc) ((vc)->v) @@ -849,9 +856,7 @@ struct vcache { struct lock__bsd__ rwlock; #endif #ifdef AFS_XBSD_ENV -# if defined(AFS_NBSD50_ENV) - struct krwlock rwlock; -# elif !defined(AFS_DFBSD_ENV) +#if !defined(AFS_DFBSD_ENV) && !defined(AFS_NBSD_ENV) struct lock rwlock; #endif #endif diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c index 1b22812..851a09f 100644 --- a/src/afs/afs_daemons.c +++ b/src/afs/afs_daemons.c @@ -182,25 +182,6 @@ afs_Daemon(void) afs_FlushActiveVcaches(0); /* flush NFS writes */ afs_FlushVCBs(1); /* flush queued callbacks */ -#if defined(AFS_NBSD50_ENV) - /* XXXX */ - { - int c1, c2; - c1 = ISAFS_GLOCK(); /* this thread owns the GLOCK */ - if (!c1) { - c2 = mutex_tryenter(&afs_global_mtx); /* not held either */ - if (c2) - AFS_GUNLOCK(); - } - else - c2 = 0; - printf("afs_daemons periodic glock check: curthread owns glock %s; " - "glock held somewhere %s\n", - c1 ? "true" : "false", - c2 ? "true" : "false"); - } -#endif - afs_MaybeWakeupTruncateDaemon(); /* free cache space if have too */ rx_CheckPackets(); /* Does RX need more packets? */ diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c index 3154474..c414d56 100644 --- a/src/afs/afs_init.c +++ b/src/afs/afs_init.c @@ -32,7 +32,7 @@ /* Exported variables */ struct osi_dev cacheDev; /*Cache device */ afs_int32 cacheInfoModTime; /*Last time cache info modified */ -#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_NBSD_ENV) struct mount *afs_cacheVfsp = 0; #elif defined(AFS_LINUX20_ENV) struct super_block *afs_cacheSBp = 0; @@ -420,6 +420,8 @@ afs_InitCacheInfo(char *afile) if (afs_cacheVfsp && ((st = *(vfs_statfs(afs_cacheVfsp))),1)) #elif defined(AFS_FBSD80_ENV) if (!VFS_STATFS(filevp->v_mount, &st)) +#elif defined(AFS_NBSD50_ENV) + if (!VFS_STATVFS(filevp->v_vfsp, &st)) #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) if (!VFS_STATFS(filevp->v_mount, &st, osi_curproc())) #else diff --git a/src/afs/afs_osi.c b/src/afs/afs_osi.c index d2fafff..5496147 100644 --- a/src/afs/afs_osi.c +++ b/src/afs/afs_osi.c @@ -55,7 +55,7 @@ struct lock__bsd__ afs_global_lock; #if defined(AFS_XBSD_ENV) && !defined(AFS_FBSD_ENV) # if defined(AFS_NBSD50_ENV) -struct kmutex afs_global_mtx; +kmutex_t afs_global_mtx; # else struct lock afs_global_lock; afs_proc_t *afs_global_owner; diff --git a/src/afs/afs_osi_alloc.c b/src/afs/afs_osi_alloc.c index 726ccff..1e3648a 100644 --- a/src/afs/afs_osi_alloc.c +++ b/src/afs/afs_osi_alloc.c @@ -39,7 +39,6 @@ static struct osi_packet { static char memZero; /* address of 0 bytes for kmem_alloc */ -#if !defined(AFS_NBSD_ENV) || defined(AFS_NBSD50_ENV) void * afs_osi_Alloc(size_t size) { @@ -84,8 +83,6 @@ afs_osi_FreeStr(char *x) afs_osi_Free(x, strlen(x) + 1); } -#endif /* !AFS_NBSD_ENV && !defined(AFS_NBSD50_ENV) */ - #ifndef AFS_PRIVATE_OSI_ALLOCSPACES /* free space allocated by AllocLargeSpace. Also called by mclput when freeing diff --git a/src/afs/afs_osi_pag.c b/src/afs/afs_osi_pag.c index c888605..4dbdcbd 100644 --- a/src/afs/afs_osi_pag.c +++ b/src/afs/afs_osi_pag.c @@ -193,6 +193,8 @@ int afs_setpag(afs_ucred_t **credpp) #elif defined(AFS_FBSD_ENV) afs_setpag(struct thread *td, void *args) +#elif defined(AFS_NBSD_ENV) +afs_setpag(afs_proc_t *p, const void *args, register_t *retval) #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) afs_setpag(afs_proc_t *p, void *args, int *retval) #else @@ -225,8 +227,7 @@ afs_setpag(void) #elif defined(AFS_FBSD_ENV) code = AddPag(td, genpag(), &td->td_ucred); #elif defined(AFS_NBSD40_ENV) - /* XXXX won't work */ - code = AddPag(p, genpag(), (afs_ucred_t **) osi_curcred()); + code = AddPag(p, genpag(), &p->l_proc->p_cred); #elif defined(AFS_XBSD_ENV) code = AddPag(p, genpag(), &p->p_rcred); #elif defined(AFS_AIX41_ENV) @@ -433,8 +434,6 @@ AddPag(afs_int32 aval, afs_ucred_t **credpp) AFS_STATCNT(AddPag); #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) if ((code = setpag(p, credpp, aval, &newpag, 0))) -#elif defined(AFS_NBSD40_ENV) - if ((code = setpag(p, (void *) credpp, aval, &newpag, 0))) #else if ((code = setpag(credpp, aval, &newpag, 0))) #endif @@ -558,13 +557,12 @@ osi_get_group_pag(afs_ucred_t *cred) ngroups = crgetngroups(cred); #endif #if defined(AFS_NBSD40_ENV) -#warning com afs_ucred_t w/magic will not work if (cred == NOCRED || cred == FSCRED) return NOPAG; if (osi_crngroups(cred) < 3) return NOPAG; - g0 = osi_crgroupbyid(cred, 0); - g1 = osi_crgroupbyid(cred, 1); + g0 = osi_crgroupbyid(cred, 1); + g1 = osi_crgroupbyid(cred, 2); #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) if (cred == NOCRED || cred == FSCRED) return NOPAG; diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index 6540d26..d39d211 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -810,6 +810,10 @@ afs_xioctl(struct thread *td, struct ioctl_args *uap, register_t *retval) { afs_proc_t *p = td->td_proc; +# elif defined(AFS_NBSD_ENV) +int +afs_xioctl(afs_proc_t *p, const struct sys_ioctl_args *uap, register_t *retval) +{ # else struct ioctl_args { int fd; @@ -818,7 +822,7 @@ struct ioctl_args { }; int -afs_xioctl(afs_proc_t *p, struct ioctl_args *uap, register_t *retval) +afs_xioctl(afs_proc_t *p, const struct ioctl_args *uap, register_t *retval) { # endif struct filedesc *fdp; @@ -827,14 +831,19 @@ afs_xioctl(afs_proc_t *p, struct ioctl_args *uap, register_t *retval) struct file *fd; AFS_STATCNT(afs_xioctl); -# if defined(AFS_NBSD40_ENV) - fdp = p->l_proc->p_fd; -# else +#if defined(AFS_NBSD40_ENV) + fdp = p->l_proc->p_fd; +#else fdp = p->p_fd; #endif - if ((u_int) uap->fd >= fdp->fd_nfiles - || (fd = fdp->fd_ofiles[uap->fd]) == NULL) +#if defined(AFS_NBSD50_ENV) + if ((fd = fd_getfile(SCARG(uap, fd))) == NULL) + return (EBADF); +#else + if ((uap->fd >= fdp->fd_nfiles) + || ((fd = fdp->fd_ofiles[uap->fd]) == NULL)) return EBADF; +#endif if ((fd->f_flag & (FREAD | FWRITE)) == 0) return EBADF; /* first determine whether this is any sort of vnode */ @@ -847,19 +856,32 @@ afs_xioctl(afs_proc_t *p, struct ioctl_args *uap, register_t *retval) # else tvc = VTOAFS((struct vnode *)fd->f_data); /* valid, given a vnode */ # endif - if (tvc && IsAfsVnode(AFSTOV(tvc))) { + if (tvc && IsAfsVnode((struct vnode *)fd->f_data)) { /* This is an AFS vnode */ - if (((uap->com >> 8) & 0xff) == 'V') { +#if defined(AFS_NBSD50_ENV) + if (((SCARG(uap, com) >> 8) & 0xff) == 'V') { +#else + if (((uap->com >> 8) & 0xff) == 'V') { +#endif struct afs_ioctl *datap; + printf("%s %lx\n", __func__, SCARG(uap, com)); AFS_GLOCK(); datap = osi_AllocSmallSpace(AFS_SMALLOCSIZ); +#if defined(AFS_NBSD50_ENV) + code = copyin_afs_ioctl(SCARG(uap, data), datap); +#else code = copyin_afs_ioctl((char *)uap->arg, datap); +#endif if (code) { osi_FreeSmallSpace(datap); AFS_GUNLOCK(); return code; } +#if defined(AFS_NBSD50_ENV) + code = HandleIoctl(tvc, SCARG(uap, com), datap); +#else code = HandleIoctl(tvc, uap->com, datap); +#endif osi_FreeSmallSpace(datap); AFS_GUNLOCK(); ioctlDone = 1; @@ -867,14 +889,17 @@ afs_xioctl(afs_proc_t *p, struct ioctl_args *uap, register_t *retval) } } +#if defined(AFS_NBSD50_ENV) + fd_putfile(SCARG(uap, fd)); +#endif + if (!ioctlDone) { # if defined(AFS_FBSD_ENV) return ioctl(td, uap); # elif defined(AFS_OBSD_ENV) code = sys_ioctl(p, uap, retval); # elif defined(AFS_NBSD_ENV) - struct lwp *l = osi_curproc(); - code = sys_ioctl(l, uap, retval); + code = sys_ioctl(p, uap, retval); # endif } diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 11d49fc..f7a8f93 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -421,8 +421,13 @@ extern int afs_icl_Event0(struct afs_icl_set *setp, extern void afs_icl_AppendRecord(struct afs_icl_log *logp, afs_int32 op, afs_int32 types, long p1, long p2, long p3, long p4); +#if defined(AFS_NBSD_ENV) +extern int Afscall_icl(long opcode, long p1, long p2, long p3, long p4, + register_t *retval); +#else extern int Afscall_icl(long opcode, long p1, long p2, long p3, long p4, long *retval); +#endif #ifdef AFS_DARWIN100_ENV extern int Afscall64_icl(int opcode, user_addr_t p1, user_addr_t p2, user_addr_t p3, user_addr_t p4, int *retval); @@ -582,6 +587,8 @@ extern void shutdown_osinet(void); extern int afs_setpag(afs_ucred_t **credpp); #elif defined(AFS_FBSD_ENV) extern int afs_setpag(struct thread *td, void *args); +#elif defined(AFS_NBSD_ENV) +extern int afs_setpag(afs_proc_t *p, const void *args, register_t *retval); #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) extern int afs_setpag(afs_proc_t *p, void *args, int *retval); #else @@ -680,8 +687,13 @@ extern int afs_syscall_icreate(afs_uint32, afs_uint32, afs_uint32, afs_uint32, a extern int afs_syscall_iopen(int, ino_t, int, rval_t *); extern int afs_syscall_iincdec(int, int, int, int); #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) +#if defined(AFS_NBSD_ENV) +extern int afs_syscall_icreate(long, long, long, long, long, long, register_t *); +extern int afs_syscall_iopen(int dev, int inode, int usrmod, register_t *); +#else extern int afs_syscall_icreate(long, long, long, long, long, long, long*); extern int afs_syscall_iopen(int dev, int inode, int usrmod, long *retval); +#endif extern int afs_syscall_iincdec(int dev, int inode, int inode_p1, int amount); #else extern int afs_syscall_icreate(long, long, long, long, long, long); @@ -720,8 +732,8 @@ extern int usr_setpag(afs_ucred_t **cred, afs_uint32 pagvalue, extern int setpag(struct thread *td, struct ucred **cred, afs_uint32 pagvalue, afs_uint32 * newpag, int change_parent); -# elif defined(AFS_NBSD40_ENV) -extern int setpag(struct proc *proc, afs_ucred_t *cred, afs_uint32 pagvalue, +# elif defined(AFS_NBSD_ENV) +extern int setpag(afs_proc_t *proc, afs_ucred_t **cred, afs_uint32 pagvalue, afs_uint32 * newpag, int change_parent); # else extern int setpag(afs_proc_t *proc, struct ucred **cred, afs_uint32 pagvalue, @@ -743,8 +755,11 @@ extern void osi_VM_StoreAllSegments(struct vcache *avc); extern void osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync); extern void osi_VM_FlushPages(struct vcache *avc, afs_ucred_t *credp); -extern void osi_VM_Truncate(struct vcache *avc, int alen, - afs_ucred_t *acred); +#if !defined(AFS_NBSD_ENV) +extern void osi_VM_Truncate(struct vcache *avc, int alen, afs_ucred_t *acred); +#else +extern void osi_VM_Truncate(struct vcache *avc, voff_t alen, afs_ucred_t *acred); +#endif extern void osi_VM_TryReclaim(struct vcache *avc, int *slept); extern void osi_VM_NukePages(struct vnode *vp, off_t offset, off_t size); extern int osi_VM_Setup(struct vcache *avc, int force); @@ -925,6 +940,8 @@ extern int afs3_syscall(afs_proc_t *p, void *args, unsigned int *retval); /* afs3_syscall prototype is in sys/sysproto.h */ #elif defined(AFS_FBSD_ENV) extern int afs3_syscall(struct thread *p, void *args); +#elif defined(AFS_NBSD50_ENV) +extern int afs3_syscall(afs_proc_t *p, const void *args, register_t *retval); #elif defined(AFS_NBSD40_ENV) extern int afs3_syscall(struct lwp *p, void *args); #else diff --git a/src/afs/afs_syscall.c b/src/afs/afs_syscall.c index 3bb6f48..6b7daeb 100644 --- a/src/afs/afs_syscall.c +++ b/src/afs/afs_syscall.c @@ -479,11 +479,10 @@ afs3_syscall(struct thread *p, void *args) long *retval; #elif defined(AFS_NBSD40_ENV) int -afs3_syscall(struct lwp *p, void *args) +afs3_syscall(struct lwp *p, const void *args, register_t *retval) { /* see osi_machdep.h */ struct afs_sysargs *uap = (struct afs_sysargs *) args; - long *retval; #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) int afs3_syscall(afs_proc_t *p, void *args, long *retval) @@ -717,8 +716,8 @@ Afs_syscall() uap->parm4, kauth_cred_get()); #elif defined(AFS_NBSD40_ENV) code = - afs_syscall_pioctl(SCARG(uap, parm1), SCARG(uap, parm2), - SCARG(uap, parm3), SCARG(uap, parm4), + afs_syscall_pioctl((char *)SCARG(uap, parm1), SCARG(uap, parm2), + (void *)SCARG(uap, parm3), SCARG(uap, parm4), kauth_cred_get()); #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) code = diff --git a/src/afs/sysincludes.h b/src/afs/sysincludes.h index 5e8ae9c..9792c63 100644 --- a/src/afs/sysincludes.h +++ b/src/afs/sysincludes.h @@ -85,21 +85,14 @@ # include # include # include -# include # include # include # include # include # include # include -# include -# include -# include -# include -# include # include # include -# include # include # include # include @@ -109,9 +102,7 @@ # include # include # ifndef MLEN -# if 0 -# include -# endif /* 0 */ +# include # include # endif /* !MLEN */ # include diff --git a/src/config/param.nbsd50.h b/src/config/param.nbsd50.h index f37b712..fb88631 100644 --- a/src/config/param.nbsd50.h +++ b/src/config/param.nbsd50.h @@ -10,16 +10,10 @@ #define AFS_MOUNT_AFS "afs" /* The name of the filesystem type. */ #define AFS_SYSCALL 210 - -#ifdef AFS_KALLOC -#undef AFS_KALLOC -#endif -#define AFS_KALLOC(s) (osi_nbsd_Alloc((s), 1 /* cansleep */)) - -#ifdef AFS_KFREE -#undef AFS_KFREE -#endif -#define AFS_KFREE(p, s) (osi_nbsd_Free((p), (s))) +#define AFS_KALLOC(n) kmem_alloc(n, KM_SLEEP) +#define AFS_KALLOC_NOSLEEP(n) kmem_alloc(n, KM_NOSLEEP) +#define AFS_KFREE kmem_free +#define VATTR_NULL vattr_null #if 0 /* including this file before sysincludes.h is canonical, but diff --git a/src/config/param.nbsd60.h b/src/config/param.nbsd60.h index f37b712..fb88631 100644 --- a/src/config/param.nbsd60.h +++ b/src/config/param.nbsd60.h @@ -10,16 +10,10 @@ #define AFS_MOUNT_AFS "afs" /* The name of the filesystem type. */ #define AFS_SYSCALL 210 - -#ifdef AFS_KALLOC -#undef AFS_KALLOC -#endif -#define AFS_KALLOC(s) (osi_nbsd_Alloc((s), 1 /* cansleep */)) - -#ifdef AFS_KFREE -#undef AFS_KFREE -#endif -#define AFS_KFREE(p, s) (osi_nbsd_Free((p), (s))) +#define AFS_KALLOC(n) kmem_alloc(n, KM_SLEEP) +#define AFS_KALLOC_NOSLEEP(n) kmem_alloc(n, KM_NOSLEEP) +#define AFS_KFREE kmem_free +#define VATTR_NULL vattr_null #if 0 /* including this file before sysincludes.h is canonical, but diff --git a/src/dir/dir.c b/src/dir/dir.c index d34769a..4ba73b9 100644 --- a/src/dir/dir.c +++ b/src/dir/dir.c @@ -32,7 +32,7 @@ # if defined(AFS_SUN56_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_FBSD_ENV) || defined(AFS_DARWIN80_ENV) # include "afs/sysincludes.h" # endif -# if !defined(AFS_SGI64_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_OBSD48_ENV) +# if !defined(AFS_SGI64_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_OBSD48_ENV) && !defined(AFS_NBSD_ENV) # include "h/user.h" # endif /* AFS_SGI64_ENV */ # include "h/uio.h" diff --git a/src/rx/NBSD/rx_kmutex.c b/src/rx/NBSD/rx_kmutex.c index c4b5782..600066c 100644 --- a/src/rx/NBSD/rx_kmutex.c +++ b/src/rx/NBSD/rx_kmutex.c @@ -13,6 +13,57 @@ * NetBSD implementation. */ -/* - * Currently everything is implemented in rx_kmutex.h - */ +#include +#include "afs/param.h" + +#if defined(AFS_NBSD50_ENV) + +#include "rx/rx_kcommon.h" +#include "rx_kmutex.h" +#include "rx/rx_kernel.h" + +int +afs_cv_wait(afs_kcondvar_t *cv, afs_kmutex_t *m, int sigok) +{ + int haveGlock = ISAFS_GLOCK(); + int retval = 0; + + if (haveGlock) + AFS_GUNLOCK(); + if (sigok) { + if (cv_wait_sig(cv, m) == 0) + retval = EINTR; + } else { + cv_wait(cv, m); + } + if (haveGlock) { + MUTEX_EXIT(m); + AFS_GLOCK(); + MUTEX_ENTER(m); + } + return retval; +} + +int +afs_cv_timedwait(afs_kcondvar_t *cv, afs_kmutex_t *m, int t, int sigok) +{ + int haveGlock = ISAFS_GLOCK(); + int retval = 0; + + if (haveGlock) + AFS_GUNLOCK(); + if (sigok) { + if (cv_timedwait_sig(cv, m, t) == 0) + retval = EINTR; + } else { + cv_timedwait(cv, m, t); + } + if (haveGlock) { + MUTEX_EXIT(m); + AFS_GLOCK(); + MUTEX_ENTER(m); + } + return retval; +} + +#endif /* AFS_NBSD50_ENV */ diff --git a/src/rx/NBSD/rx_kmutex.h b/src/rx/NBSD/rx_kmutex.h index dc75f2a..a8c7a87 100644 --- a/src/rx/NBSD/rx_kmutex.h +++ b/src/rx/NBSD/rx_kmutex.h @@ -27,6 +27,7 @@ #ifdef AFS_NBSD50_ENV #include +#include #else #include #endif @@ -35,6 +36,28 @@ #define RX_ENABLE_LOCKS 1 #define AFS_GLOBAL_RXLOCK_KERNEL +#if defined(AFS_NBSD50_ENV) +typedef kmutex_t afs_kmutex_t; + +#define MUTEX_INIT(a,b,c,d) mutex_init((a), (c), IPL_NONE) +#define MUTEX_DESTROY(a) mutex_destroy((a)) +#define MUTEX_ENTER(a) mutex_enter((a)); +#define MUTEX_TRYENTER(a) mutex_tryenter((a)) +#define MUTEX_EXIT(a) mutex_exit((a)) +#define MUTEX_ISMINE(a) mutex_owned((a)) + +typedef kcondvar_t afs_kcondvar_t; +int afs_cv_wait(afs_kcondvar_t *, afs_kmutex_t *, int); + +#define CV_INIT(a, b, c, d) cv_init(a, b) +#define CV_DESTROY(a) cv_destroy(a) +#define CV_SIGNAL(a) cv_signal(a) +#define CV_BROADCAST(a) cv_broadcast(a) +#define CV_WAIT(a, b) afs_cv_wait(a, b, 0) +#define CV_WAIT_SIG afs_cv_wait(a, b, 1) + +#else + /* * Condition variables * @@ -76,47 +99,14 @@ #define CV_SIGNAL(cv) wakeup_one(cv) #define CV_BROADCAST(cv) wakeup(cv) -/* #define osi_rxWakeup(cv) wakeup(cv) */ +#define osi_rxWakeup(cv) wakeup(cv) typedef int afs_kcondvar_t; typedef struct { -#ifdef AFS_NBSD50_ENV - struct kmutex mtx; -#else - struct lock lock; -#endif + struct lock lock; struct lwp *owner; } afs_kmutex_t; -#ifdef AFS_NBSD50_ENV -#define MUTEX_INIT(a,b,c,d) \ - do { \ - mutex_init(&(a)->mtx, (c), IPL_NONE); \ - } while(0); - -#define MUTEX_DESTROY(a) \ - do { \ - mutex_destroy(&(a)->mtx); \ - } while(0); - -#define MUTEX_ENTER(a) \ - do { \ - mutex_enter(&(a)->mtx); \ - } while(0); - -#define MUTEX_TRYENTER(a) \ - ( mutex_tryenter(&(a)->mtx) ) - -#define MUTEX_EXIT(a) \ - do { \ - mutex_exit(&(a)->mtx); \ - } while(0); - -#define MUTEX_ISMINE(a) \ - ( mutex_owned(&(a)->mtx) ) - -#else /* AFS_NBSD50_ENV */ - #define MUTEX_INIT(a,b,c,d) \ do { \ lockinit(&(a)->lock, PSOCK, "afs rx mutex", 0, 0); \ diff --git a/src/rx/NBSD/rx_knet.c b/src/rx/NBSD/rx_knet.c index f4cb558..e08b278 100644 --- a/src/rx/NBSD/rx_knet.c +++ b/src/rx/NBSD/rx_knet.c @@ -69,10 +69,15 @@ osi_StopListener(void) { struct proc *p; - soclose(rx_socket); - p = pfind(rxk_ListenerPid); + solock(rx_socket); + soshutdown(rx_socket, SHUT_RDWR); + sounlock(rx_socket); + mutex_enter(proc_lock); + p = proc_find(rxk_ListenerPid); + mutex_exit(proc_lock); if (p) psignal(p, SIGUSR1); + soclose(rx_socket); } /* diff --git a/src/rx/rx_kcommon.c b/src/rx/rx_kcommon.c index e223469..2f5b05f 100644 --- a/src/rx/rx_kcommon.c +++ b/src/rx/rx_kcommon.c @@ -929,12 +929,18 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport) } } #else +#if defined(AFS_NBSD_ENV) + solock(newSocket); +#endif code = soreserve(newSocket, 50000, 50000); if (code) { code = soreserve(newSocket, 32766, 32766); if (code) osi_Panic("osi_NewSocket: last attempt to reserve 32K failed!\n"); } +#if defined(AFS_NBSD_ENV) + sounlock(newSocket); +#endif #endif #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) #if defined(AFS_FBSD_ENV) diff --git a/src/rx/rx_packet.c b/src/rx/rx_packet.c index 138ca53..6f10329 100644 --- a/src/rx/rx_packet.c +++ b/src/rx/rx_packet.c @@ -1735,6 +1735,10 @@ m_cpytoiovec(struct mbuf *m, int off, int len, struct iovec iovs[], int niovs) #endif /* AFS_SUN5_ENV */ #if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN80_ENV) +#if defined(AFS_NBSD_ENV) +int +rx_mb_to_packet(struct mbuf *amb, void (*free) (struct mbuf *), int hdr_len, int data_len, struct rx_packet *phandle) +#else int rx_mb_to_packet(amb, free, hdr_len, data_len, phandle) #if defined(AFS_SUN5_ENV) || defined(AFS_HPUX110_ENV) @@ -1745,6 +1749,7 @@ rx_mb_to_packet(amb, free, hdr_len, data_len, phandle) void (*free) (); struct rx_packet *phandle; int hdr_len, data_len; +#endif /* AFS_NBSD_ENV */ { int code; -- 1.9.4