From 3e843e3dabbbe0fcfd0dbc55216ae1c5a3d94fe9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Love=20H=C3=B6rnquist-=C3=85strand?= Date: Tue, 1 Jan 2002 18:57:18 +0000 Subject: [PATCH] netbsd-server-support-20020101 support for fileserver (namei) on netbsd ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== like openbsd, stripping on netbsd strips libraries --- Makefile.in | 6 +- acinclude.m4 | 7 + src/afs/NBSD/opt_posix.h | 2 + src/afs/NBSD/osi_file.c | 238 ++++++ src/afs/NBSD/osi_groups.c | 164 +++++ src/afs/NBSD/osi_inode.c | 283 +++++++ src/afs/NBSD/osi_inode.h | 70 ++ src/afs/NBSD/osi_machdep.h | 91 +++ src/afs/NBSD/osi_misc.c | 38 + src/afs/NBSD/osi_sleep.c | 188 +++++ src/afs/NBSD/osi_vfsops.c | 485 ++++++++++++ src/afs/NBSD/osi_vm.c | 214 ++++++ src/afs/NBSD/osi_vnodeops.c | 1095 ++++++++++++++++++++++++++++ src/cf/osconf.m4 | 12 + src/config/Makefile.config.in | 1 + src/config/param.i386_nbsd15.h | 110 +++ src/config/param.i386_nbsd15_usr.h | 58 ++ src/gtx/curseswindows.c | 3 + src/libafs/MakefileProto.NBSD.in | 130 ++++ src/libuafs/MakefileProto.NBSD.in | 76 ++ src/lwp/Makefile.in | 2 +- src/pinstall/install.c | 8 +- src/rx/NBSD/rx_kmutex.h | 107 +++ src/rx/NBSD/rx_knet.c | 167 +++++ src/usd/usd_file.c | 2 +- src/uss/uss_common.h | 2 +- src/venus/up.c | 2 +- 27 files changed, 3550 insertions(+), 11 deletions(-) create mode 100644 src/afs/NBSD/opt_posix.h create mode 100644 src/afs/NBSD/osi_file.c create mode 100644 src/afs/NBSD/osi_groups.c create mode 100644 src/afs/NBSD/osi_inode.c create mode 100644 src/afs/NBSD/osi_inode.h create mode 100644 src/afs/NBSD/osi_machdep.h create mode 100644 src/afs/NBSD/osi_misc.c create mode 100644 src/afs/NBSD/osi_sleep.c create mode 100644 src/afs/NBSD/osi_vfsops.c create mode 100644 src/afs/NBSD/osi_vm.c create mode 100644 src/afs/NBSD/osi_vnodeops.c create mode 100644 src/config/param.i386_nbsd15.h create mode 100644 src/config/param.i386_nbsd15_usr.h create mode 100644 src/libafs/MakefileProto.NBSD.in create mode 100644 src/libuafs/MakefileProto.NBSD.in create mode 100644 src/rx/NBSD/rx_kmutex.h create mode 100644 src/rx/NBSD/rx_knet.c diff --git a/Makefile.in b/Makefile.in index 4d20f8b05..f022fcfb0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -255,7 +255,7 @@ bozo: project ntp audit vfsck: vol set -x; \ case ${SYS_NAME} in \ - sgi_* | *linux* | rs_aix42 | ppc_darwin* | hp_ux* | *fbsd* | *_obsd* ) \ + sgi_* | *linux* | rs_aix42 | ppc_darwin* | hp_ux* | *fbsd* | *_obsd* | *_nbsd* ) \ echo skip vfsck for ${SYS_NAME} ;; \ * ) \ ${COMPILE_PART1} vfsck ${COMPILE_PART2} ;; \ @@ -276,7 +276,7 @@ login: project kauth rxkad echo Skipping pam/login for parisc_linux24 ;; \ sun4x_* | sunx86_* | hp_ux11* | *linux* | *fbsd* ) \ ${COMPILE_PART1} pam ${COMPILE_PART2} ;; \ - ppc_darwin* | *_obsd* ) \ + ppc_darwin* | *_obsd* | *_nbsd* ) \ echo Skipping login for ${SYS_NAME} ;; \ * ) \ ${COMPILE_PART1} login ${COMPILE_PART2} ;; \ @@ -342,7 +342,7 @@ libafs_tree: libafs_setup ${KERNELDIR} libuafs: lwp libuafs_setup ${UKERNELDIR} set -x; \ case ${SYS_NAME} in \ - hp_ux102* | *_obsd* ) \ + hp_ux102* | *_obsd* | *_nbsd*) \ echo Skipping libuafs for ${SYS_NAME} ;; \ * ) \ ${COMPILE_PART1} libuafs ${COMPILE_PART2} ;; \ diff --git a/acinclude.m4 b/acinclude.m4 index 07ad5f18e..a05ca4be0 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -185,6 +185,10 @@ case $system in MKAFS_OSTYPE=FBSD AC_MSG_RESULT(i386_fbsd) ;; + *-netbsd*) + MKAFS_OSTYPE=NBSD + AC_MSG_RESULT(i386_nbsd) + ;; *-openbsd*) MKAFS_OSTYPE=OBSD AC_MSG_RESULT(i386_obsd) @@ -202,6 +206,9 @@ else i?86-*-freebsd4.2*) AFS_SYSNAME="i386_fbsd_42" ;; + i?86-*-netbsd*1.5*) + AFS_SYSNAME="i386_nbsd15" + ;; hppa*-hp-hpux11*) AFS_SYSNAME="hp_ux110" ;; diff --git a/src/afs/NBSD/opt_posix.h b/src/afs/NBSD/opt_posix.h new file mode 100644 index 000000000..0215c63ec --- /dev/null +++ b/src/afs/NBSD/opt_posix.h @@ -0,0 +1,2 @@ +#define P1003_1B 1 +#define _KPOSIX_PRIORITY_SCHEDULING 1 diff --git a/src/afs/NBSD/osi_file.c b/src/afs/NBSD/osi_file.c new file mode 100644 index 000000000..26e4b7ccb --- /dev/null +++ b/src/afs/NBSD/osi_file.c @@ -0,0 +1,238 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +#include +#include "../afs/param.h" + +RCSID("$Header$"); + +#include "../afs/sysincludes.h" /* Standard vendor system headers */ +#include "../afs/afsincludes.h" /* Afs-based standard headers */ +#include "../afs/afs_stats.h" /* afs statistics */ + + +int afs_osicred_initialized=0; +struct AFS_UCRED afs_osi_cred; +afs_lock_t afs_xosi; /* lock is for tvattr */ +extern struct osi_dev cacheDev; +extern struct mount *afs_cacheVfsp; + + +void *osi_UFSOpen(ainode) + afs_int32 ainode; +{ + struct inode *ip; + register struct osi_file *afile = NULL; + extern int cacheDiskType; + afs_int32 code = 0; + int dummy; + AFS_STATCNT(osi_UFSOpen); + if(cacheDiskType != AFS_FCACHE_TYPE_UFS) { + osi_Panic("UFSOpen called for non-UFS cache\n"); + } + if (!afs_osicred_initialized) { + /* valid for alpha_osf, SunOS, Ultrix */ + memset((char *)&afs_osi_cred, 0, sizeof(struct AFS_UCRED)); + afs_osi_cred.cr_ref++; + afs_osicred_initialized = 1; + } + afile = (struct osi_file *) osi_AllocSmallSpace(sizeof(struct osi_file)); + AFS_GUNLOCK(); + code = igetinode(afs_cacheVfsp, (dev_t) cacheDev.dev, (ino_t)ainode, &ip, &dummy); + AFS_GLOCK(); + if (code) { + osi_FreeSmallSpace(afile); + osi_Panic("UFSOpen: igetinode failed"); + } + IN_UNLOCK(ip); + afile->vnode = ITOV(ip); + afile->size = VTOI(afile->vnode)->i_size; + afile->offset = 0; + afile->proc = (int (*)()) 0; + afile->inum = ainode; /* for hint validity checking */ + return (void *)afile; +} + +afs_osi_Stat(afile, astat) + register struct osi_file *afile; + register struct osi_stat *astat; { + register afs_int32 code; + struct vattr tvattr; + AFS_STATCNT(osi_Stat); + MObtainWriteLock(&afs_xosi,320); + AFS_GUNLOCK(); + VOP_GETATTR(afile->vnode, &tvattr, &afs_osi_cred, code); + AFS_GLOCK(); + if (code == 0) { + astat->size = tvattr.va_size; + astat->blksize = tvattr.va_blocksize; + astat->mtime = tvattr.va_mtime.tv_sec; + astat->atime = tvattr.va_atime.tv_sec; + } + MReleaseWriteLock(&afs_xosi); + return code; +} + +osi_UFSClose(afile) + register struct osi_file *afile; + { + AFS_STATCNT(osi_Close); + if(afile->vnode) { + AFS_RELE(afile->vnode); + } + + osi_FreeSmallSpace(afile); + return 0; + } + +osi_UFSTruncate(afile, asize) + register struct osi_file *afile; + afs_int32 asize; { + struct AFS_UCRED *oldCred; + struct vattr tvattr; + register afs_int32 code; + struct osi_stat tstat; + AFS_STATCNT(osi_Truncate); + + /* This routine only shrinks files, and most systems + * have very slow truncates, even when the file is already + * small enough. Check now and save some time. + */ + code = afs_osi_Stat(afile, &tstat); + if (code || tstat.size <= asize) return code; + MObtainWriteLock(&afs_xosi,321); + VATTR_NULL(&tvattr); + /* note that this credential swapping stuff is only necessary because + of ufs's references directly to cred instead of to + credentials parameter. Probably should fix ufs some day. */ + oldCred = curproc->p_cred->pc_ucred; /* remember old credentials pointer */ + curproc->p_cred->pc_ucred = &afs_osi_cred; + /* temporarily use superuser credentials */ + tvattr.va_size = asize; + AFS_GUNLOCK(); + VOP_SETATTR(afile->vnode, &tvattr, &afs_osi_cred, code); + AFS_GLOCK(); + curproc->p_cred->pc_ucred = oldCred; /* restore */ + MReleaseWriteLock(&afs_xosi); + return code; +} + +void osi_DisableAtimes(avp) +struct vnode *avp; +{ + struct inode *ip = VTOI(avp); + ip->i_flag &= ~IACC; +} + + +/* Generic read interface */ +afs_osi_Read(afile, offset, aptr, asize) + register struct osi_file *afile; + int offset; + char *aptr; + afs_int32 asize; { + struct AFS_UCRED *oldCred; + unsigned int resid; + register afs_int32 code; + register afs_int32 cnt1=0; + AFS_STATCNT(osi_Read); + + /** + * If the osi_file passed in is NULL, panic only if AFS is not shutting + * down. No point in crashing when we are already shutting down + */ + if ( !afile ) { + if ( !afs_shuttingdown ) + osi_Panic("osi_Read called with null param"); + else + return EIO; + } + + if (offset != -1) afile->offset = offset; + AFS_GUNLOCK(); + code = gop_rdwr(UIO_READ, afile->vnode, (caddr_t) aptr, asize, afile->offset, + AFS_UIOSYS, IO_UNIT, &afs_osi_cred, &resid); + AFS_GLOCK(); + if (code == 0) { + code = asize - resid; + afile->offset += code; + osi_DisableAtimes(afile->vnode); + } + else { + afs_Trace2(afs_iclSetp, CM_TRACE_READFAILED, ICL_TYPE_INT32, resid, + ICL_TYPE_INT32, code); + code = -1; + } + return code; +} + +/* Generic write interface */ +afs_osi_Write(afile, offset, aptr, asize) + register struct osi_file *afile; + char *aptr; + afs_int32 offset; + afs_int32 asize; { + struct AFS_UCRED *oldCred; + unsigned int resid; + register afs_int32 code; + AFS_STATCNT(osi_Write); + if ( !afile ) + osi_Panic("afs_osi_Write called with null param"); + if (offset != -1) afile->offset = offset; + { + struct ucred *tmpcred = curproc->p_cred->pc_ucred; + curproc->p_cred->pc_ucred = &afs_osi_cred; + AFS_GUNLOCK(); + code = gop_rdwr(UIO_WRITE, afile->vnode, (caddr_t) aptr, asize, afile->offset, + AFS_UIOSYS, IO_UNIT, &afs_osi_cred, &resid); + AFS_GLOCK(); + curproc->p_cred->pc_ucred = tmpcred; + } + if (code == 0) { + code = asize - resid; + afile->offset += code; + } + else { + code = -1; + } + if (afile->proc) { + (*afile->proc)(afile, code); + } + return code; +} + + +/* This work should be handled by physstrat in ca/machdep.c. + This routine written from the RT NFS port strategy routine. + It has been generalized a bit, but should still be pretty clear. */ +int afs_osi_MapStrategy(aproc, bp) + int (*aproc)(); + register struct buf *bp; +{ + afs_int32 returnCode; + + AFS_STATCNT(osi_MapStrategy); + returnCode = (*aproc) (bp); + + return returnCode; +} + + + +void +shutdown_osifile() +{ + extern int afs_cold_shutdown; + + AFS_STATCNT(shutdown_osifile); + if (afs_cold_shutdown) { + afs_osicred_initialized = 0; + } +} + diff --git a/src/afs/NBSD/osi_groups.c b/src/afs/NBSD/osi_groups.c new file mode 100644 index 000000000..77f4d6489 --- /dev/null +++ b/src/afs/NBSD/osi_groups.c @@ -0,0 +1,164 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +/* + * osi_groups.c + * + * Implements: + * Afs_xsetgroups (syscall) + * setpag + * + */ +#include +#include "../afs/param.h" + +RCSID("$Header$"); + +#include "../afs/sysincludes.h" +#include "../afs/afsincludes.h" +#include "../afs/afs_stats.h" /* statistics */ + +#define NOCRED ((struct ucred *) -1) +#define NOUID ((uid_t) -1) +#define NOGID ((gid_t) -1) + + +static int +afs_getgroups( + struct ucred *cred, + int ngroups, + gid_t *gidset); + +static int +afs_setgroups( + struct proc *proc, + struct ucred **cred, + int ngroups, + gid_t *gidset, + int change_parent); + +int +Afs_xsetgroups(p, args, retval) + struct proc *p; + void *args; + int *retval; +{ + int code = 0; + struct vrequest treq; + + AFS_STATCNT(afs_xsetgroups); + AFS_GLOCK(); + + /* code = afs_InitReq(&treq, u.u_cred); */ + code = afs_InitReq(&treq, curproc->p_cred->pc_ucred); + AFS_GUNLOCK(); + if (code) return code; + + code = 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. + */ + if (PagInCred(curproc->p_cred->pc_ucred) == NOPAG) { + if (((treq.uid >> 24) & 0xff) == 'A') { + AFS_GLOCK(); + /* we've already done a setpag, so now we redo it */ + AddPag(p, treq.uid, &p->p_rcred); + AFS_GUNLOCK(); + } + } + return code; +} + + +int +setpag(proc, cred, pagvalue, newpag, change_parent) + struct proc *proc; + struct ucred **cred; + afs_uint32 pagvalue; + afs_uint32 *newpag; + afs_uint32 change_parent; +{ + gid_t gidset[NGROUPS]; + int ngroups, code; + int j; + + AFS_STATCNT(setpag); + ngroups = afs_getgroups(*cred, NGROUPS, gidset); + if (afs_get_pag_from_groups(gidset[0], gidset[1]) == NOPAG) { + /* We will have to shift grouplist to make room for pag */ + if (ngroups + 2 > NGROUPS) { + return (E2BIG); + } + for (j = ngroups -1; j >= 0; j--) { + gidset[j+2] = gidset[j]; + } + ngroups += 2; + } + *newpag = (pagvalue == -1 ? genpag(): pagvalue); + afs_get_groups_from_pag(*newpag, &gidset[0], &gidset[1]); + code = afs_setgroups(proc, cred, ngroups, gidset, change_parent); + return code; +} + + +static int +afs_getgroups( + struct ucred *cred, + int ngroups, + gid_t *gidset) +{ + int ngrps, savengrps; + gid_t *gp; + + AFS_STATCNT(afs_getgroups); + savengrps = ngrps = MIN(ngroups, cred->cr_ngroups); + gp = cred->cr_groups; + while (ngrps--) + *gidset++ = *gp++; + return savengrps; +} + + + +static int +afs_setgroups( + struct proc *proc, + struct ucred **cred, + int ngroups, + gid_t *gidset, + int change_parent) +{ + int ngrps; + int i; + gid_t *gp; + struct ucred *newcr, *cr; + + AFS_STATCNT(afs_setgroups); + /* + * The real setgroups() call does this, so maybe we should too. + * + */ + if (ngroups > NGROUPS) + return EINVAL; + cr = *cred; + if (!change_parent) { + crhold(cr); + newcr = crcopy(cr); + } else + newcr = cr; + newcr->cr_ngroups = ngroups; + gp = newcr->cr_groups; + while (ngroups--) + *gp++ = *gidset++; + if (!change_parent) { + substitute_real_creds(proc, NOUID, NOUID, NOGID, NOGID, newcr); + } + *cred = newcr; + return(0); +} diff --git a/src/afs/NBSD/osi_inode.c b/src/afs/NBSD/osi_inode.c new file mode 100644 index 000000000..6d8b88dba --- /dev/null +++ b/src/afs/NBSD/osi_inode.c @@ -0,0 +1,283 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +/* + * FreeBSD inode operations + * + * Implements: + * + */ +#include +#include "../afs/param.h" + +RCSID("$Header$"); + +#include "../afs/sysincludes.h" /* Standard vendor system headers */ +#include "../afs/afsincludes.h" /* Afs-based standard headers */ +#include "../afs/osi_inode.h" +#include "../afs/afs_stats.h" /* statistics stuff */ +#include +#include +#include +#include + +getinode(fs, dev, inode, ipp, perror) + struct mount *fs; + struct inode **ipp; + dev_t dev; + ino_t inode; + int *perror; +{ + register struct vnode *vp; + char fake_vnode[FAKE_INODE_SIZE]; + struct inode *ip; + int code; + + *ipp = 0; + *perror = 0; + if (!fs) { + register struct ufsmount *ump; + register struct vnode *vp; + register struct mount *mp; + + MOUNTLIST_LOCK(); + if (mp = TAILQ_FIRST(&mountlist)) do { + /* + * XXX Also do the test for MFS + */ +#undef m_data +#undef m_next + if (mp->mnt_stat.f_type == MOUNT_UFS) { + MOUNTLIST_UNLOCK(); + ump = VFSTOUFS(mp); + if (ump->um_fs == NULL) + break; + if (ump->um_dev == dev) { + fs = ump->um_mountp; + } + MOUNTLIST_LOCK(); + } + mp = TAILQ_NEXT(mp, mnt_list); + } while (mp != TAILQ_FIRST(&mountlist)); + MOUNTLIST_UNLOCK(); + if (!fs) + return(ENXIO); + } + vp = (struct vnode *) fake_vnode; + fake_inode_init(vp, fs); + code = iget(VTOI(vp), inode, &ip, 0); + if (code != 0) { + *perror = BAD_IGET; + return code; + } else { + *ipp = ip; + return(0); + } +} + +igetinode(vfsp, dev, inode, ipp, perror) + struct inode **ipp; + struct mount *vfsp; + dev_t dev; + ino_t inode; + int *perror; +{ + struct inode *pip, *ip; + extern struct osi_dev cacheDev; + register int code = 0; + + *perror = 0; + + AFS_STATCNT(igetinode); + + if ((code = getinode(vfsp, dev, inode, &ip, perror)) != 0) { + return(code); + } + + if (ip->i_mode == 0) { + /* Not an allocated inode */ + iforget(ip); + return(ENOENT); + } + + if (ip->i_nlink == 0 || (ip->i_mode&IFMT) != IFREG) { + iput(ip); + return(ENOENT); + } + + *ipp = ip; + return(0); +} + +iforget(ip) +struct inode *ip; +{ + struct vnode *vp = ITOV(ip); + + AFS_STATCNT(iforget); + + VN_LOCK(vp); + /* this whole thing is too wierd. Why??? XXX */ + if (vp->v_usecount == 1) { + VN_UNLOCK(vp); + idrop(ip); + } else { + VN_UNLOCK(vp); + } +} + +/* + * icreate system call -- create an inode + */ +afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval) + long *retval; + long dev, near_inode, param1, param2, param3, param4; +{ + int dummy, err=0; + struct inode *ip, *newip; + register int code; + struct vnode *vp; + + AFS_STATCNT(afs_syscall_icreate); + + if (!afs_suser()) + return(EPERM); + + code = getinode(0, (dev_t)dev, 2, &ip, &dummy); + if (code) { + return(ENOENT); + } + code = ialloc(ip, (ino_t)near_inode, 0, &newip); + iput(ip); + if (code) { + return(code); + } + IN_LOCK(newip); + newip->i_flag |= IACC|IUPD|ICHG; + + newip->i_nlink = 1; + + newip->i_mode = IFREG; + + IN_UNLOCK(newip); + vp = ITOV(newip); + VN_LOCK(vp); + vp->v_type = VREG; + VN_UNLOCK(vp); + + /* + if ( !vp->v_object) + { + extern struct vfs_ubcops ufs_ubcops; + extern struct vm_ubc_object* ubc_object_allocate(); + struct vm_ubc_object* vop; + vop = ubc_object_allocate(&vp, &ufs_ubcops, + vp->v_mount->m_funnel); + VN_LOCK(vp); + vp->v_object = vop; + VN_UNLOCK(vp); + } + */ + + IN_LOCK(newip); + /* newip->i_flags |= IC_XUID|IC_XGID; */ + /* newip->i_flags &= ~IC_PROPLIST; */ + newip->i_vicep1 = param1; + if (param2 == 0x1fffffff/*INODESPECIAL*/) { + newip->i_vicep2 = ((0x1fffffff << 3) + (param4 & 0x3)); + newip->i_vicep3a = (u_short)(param3 >> 16); + newip->i_vicep3b = (u_short)param3; + } else { + newip->i_vicep2 = (((param2 >> 16) & 0x1f) << 27) + + (((param4 >> 16) & 0x1f) << 22) + + (param3 & 0x3fffff); + newip->i_vicep3a = (u_short)param4; + newip->i_vicep3b = (u_short)param2; + } + newip->i_vicemagic = VICEMAGIC; + + *retval = newip->i_number; + IN_UNLOCK(newip); + iput(newip); + return(code); +} + + +afs_syscall_iopen(dev, inode, usrmod, retval) + long *retval; + int dev, inode, usrmod; +{ + struct file *fp; + struct inode *ip; + struct vnode *vp = (struct vnode *)0; + int dummy; + int fd; + extern struct fileops vnops; + register int code; + + AFS_STATCNT(afs_syscall_iopen); + + if (!afs_suser()) + return(EPERM); + + code = igetinode(0, (dev_t)dev, (ino_t)inode, &ip, &dummy); + if (code) { + return(code); + } + if ((code = falloc(curproc, &fp, &fd)) != 0) { + iput(ip); + return(code); + } + IN_UNLOCK(ip); + + /* FreeBSD doesn't do much mp stuff yet :( */ + /* FP_LOCK(fp); */ + fp->f_flag = (usrmod) & FMASK; + fp->f_type = DTYPE_VNODE; + fp->f_ops = &vnops; + fp->f_data = (caddr_t)ITOV(ip); + + /* FP_UNLOCK(fp); */ + return(0); +} + + +/* + * Support for iinc() and idec() system calls--increment or decrement + * count on inode. + * Restricted to super user. + * Only VICEMAGIC type inodes. + */ +afs_syscall_iincdec(dev, inode, inode_p1, amount) + int dev, inode, inode_p1, amount; +{ + int dummy; + struct inode *ip; + register int code; + + if (!afs_suser()) + return(EPERM); + + code = igetinode(0, (dev_t)dev, (ino_t)inode, &ip, &dummy); + if (code) { + return(code); + } + if (!IS_VICEMAGIC(ip)) { + return(EPERM); + } else if (ip->i_vicep1 != inode_p1) { + return(ENXIO); + } + ip->i_nlink += amount; + if (ip->i_nlink == 0) { + CLEAR_VICEMAGIC(ip); + } + ip->i_flag |= ICHG; + iput(ip); + return(0); +} diff --git a/src/afs/NBSD/osi_inode.h b/src/afs/NBSD/osi_inode.h new file mode 100644 index 000000000..39c706fa1 --- /dev/null +++ b/src/afs/NBSD/osi_inode.h @@ -0,0 +1,70 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +/* + * osi_inode.h + * + * Inode information required for DUX servers and salvager. + */ +#ifndef _OSI_INODE_H_ +#define _OSI_INODE_H_ + +#define BAD_IGET -1000 + +#define VICEMAGIC 0xb61cfa84 + +#define DI_VICEP3(p) \ + ( ((u_int)((p)->di_vicep3a)) << 16 | ((u_int)((p)->di_vicep3b)) ) +#define I_VICE3(p) \ + ( ((u_int)((p)->i_vicep3a)) << 16 | ((u_int)((p)->i_vicep3b)) ) + +#define FAKE_INODE_SIZE (sizeof(struct vnode)+sizeof(struct inode)) +#define MOUNTLIST_UNLOCK() simple_lock_unlock(&mountlist_slock) +#define MOUNTLIST_LOCK() simple_lock(&mountlist_slock) + +/* FreeBSD doesn't actually have a di_proplb, so we use di_spare[0] */ +#define di_proplb di_spare[0] +/* For some reason, they're called "oldids" instead of "bc_{u,g}id" */ +#define di_bcuid di_u.oldids[0] +#define di_bcgid di_u.oldids[1] + +#define i_vicemagic i_din.di_spare[0] +#define i_vicep1 i_din.di_uid +#define i_vicep2 i_din.di_gid +#define i_vicep3a i_din.di_u.oldids[0] +#define i_vicep3b i_din.di_u.oldids[1] +#define i_vicep4 i_din.di_spare[1] /* not used */ + +#define di_vicemagic di_spare[0] +#define di_vicep1 di_uid +#define di_vicep2 di_gid +#define di_vicep3a di_u.oldids[0] +#define di_vicep3b di_u.oldids[1] +#define di_vicep4 di_spare[1] /* not used */ + +/* + * Macros for handling inode numbers: + * inode number to file system block offset. + * inode number to cylinder group number. + * inode number to file system block address. + */ +#define itoo(fs, x) ((x) % INOPB(fs)) +#define itog(fs, x) ((x) / (fs)->fs_ipg) +#define itod(fs, x) \ + ((daddr_t)(cgimin(fs, itog(fs, x)) + \ + (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs)))))) + + +#define IS_VICEMAGIC(ip) ((ip)->i_vicemagic == VICEMAGIC) +#define IS_DVICEMAGIC(dp) ((dp)->di_vicemagic == VICEMAGIC) + +#define CLEAR_VICEMAGIC(ip) (ip)->i_vicemagic = 0 +#define CLEAR_DVICEMAGIC(dp) (dp)->di_vicemagic = 0 + +#endif /* _OSI_INODE_H_ */ diff --git a/src/afs/NBSD/osi_machdep.h b/src/afs/NBSD/osi_machdep.h new file mode 100644 index 000000000..b0c044266 --- /dev/null +++ b/src/afs/NBSD/osi_machdep.h @@ -0,0 +1,91 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +/* + * + * DUX 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 + * afs_osi.h. + */ + +#ifndef _OSI_MACHDEP_H_ +#define _OSI_MACHDEP_H_ + +#include +/* #include */ +/* #include */ + +#define getpid() curproc +extern struct simplelock afs_rxglobal_lock; + +/* + * Time related macros + */ +extern struct timeval time; +#define osi_Time() (time.tv_sec) +#define afs_hz hz + +#define PAGESIZE 8192 + +#define AFS_UCRED ucred +#define AFS_PROC struct proc + +#define afs_bufferpages bufpages + +#define osi_vnhold(avc,r) do { \ + if ((avc)->vrefCount) { VN_HOLD((struct vnode *)(avc)); } \ + else osi_Panic("refcnt==0"); } while(0) + +#define gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \ + vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(cred),(aresid), curproc) + +#undef afs_suser + +#ifdef KERNEL +extern struct simplelock afs_global_lock; +#if 0 +extern thread_t afs_global_owner; +#define AFS_GLOCK() \ + do { \ + usimple_lock(&afs_global_lock); \ + osi_Assert(afs_global_owner == (thread_t)0); \ + afs_global_owner = current_thread(); \ + } while (0) +#define AFS_GUNLOCK() \ + do { \ + osi_Assert(afs_global_owner == current_thread()); \ + afs_global_owner = (thread_t)0; \ + usimple_unlock(&afs_global_lock); \ + } while(0) +#define ISAFS_GLOCK() (afs_global_owner == current_thread()) +#else +#define AFS_GLOCK() \ + do { \ + simple_lock(&afs_global_lock); \ + } while (0) +#define AFS_GUNLOCK() \ + do { \ + simple_unlock(&afs_global_lock); \ + } while(0) +#endif /* 0 */ +#define AFS_RXGLOCK() +#define AFS_RXGUNLOCK() +#define ISAFS_RXGLOCK() 1 + +#undef SPLVAR +#define SPLVAR +#undef NETPRI +#define NETPRI +#undef USERPRI +#define USERPRI +#endif /* KERNEL */ + +#endif /* _OSI_MACHDEP_H_ */ diff --git a/src/afs/NBSD/osi_misc.c b/src/afs/NBSD/osi_misc.c new file mode 100644 index 000000000..1064a1a64 --- /dev/null +++ b/src/afs/NBSD/osi_misc.c @@ -0,0 +1,38 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +/* + * osi_misc.c + * + * Implements: + * afs_suser + */ + +#include +#include "../afs/param.h" + +RCSID("$Header$"); + +#include "../afs/sysincludes.h" /* Standard vendor system headers */ +#include "../afs/afsincludes.h" /* Afs-based standard headers */ + +/* + * afs_suser() returns true if the caller is superuser, false otherwise. + * + * Note that it must NOT set errno. + */ + +afs_suser() { + int error; + + if (suser(curproc) == 0) { + return(1); + } + return(0); +} diff --git a/src/afs/NBSD/osi_sleep.c b/src/afs/NBSD/osi_sleep.c new file mode 100644 index 000000000..11f26ed59 --- /dev/null +++ b/src/afs/NBSD/osi_sleep.c @@ -0,0 +1,188 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + + +#include +#include "../afs/param.h" + +RCSID("$Header$"); + +#include "../afs/sysincludes.h" /* Standard vendor system headers */ +#include "../afs/afsincludes.h" /* Afs-based standard headers */ +#include "../afs/afs_stats.h" /* afs statistics */ + + + +static int osi_TimedSleep(char *event, afs_int32 ams, int aintok); +void afs_osi_Wakeup(char *event); +void afs_osi_Sleep(char *event); + +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, tid; + + AFS_STATCNT(osi_Wait); + endTime = osi_Time() + (ams/1000); + if (ahandle) + ahandle->proc = (caddr_t) curproc; + do { + AFS_ASSERT_GLOCK(); + code = 0; + code = 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 */ + int cond; +} 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; + newp->seq = 0; + } + newp->event = event; + newp->refcount = 1; + return newp; +} + +/* Release the specified event */ +#define relevent(evp) ((evp)->refcount--) + + +void afs_osi_Sleep(char *event) +{ + struct afs_event *evp; + int seq; + + evp = afs_getevent(event); + seq = evp->seq; + while (seq == evp->seq) { + AFS_ASSERT_GLOCK(); + assert_wait((vm_offset_t)(&evp->cond), 0); + AFS_GUNLOCK(); + thread_block(); + AFS_GLOCK(); + } + relevent(evp); +} + +/* 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. + */ +static int osi_TimedSleep(char *event, afs_int32 ams, int aintok) +{ + int code = 0; + struct afs_event *evp; + int ticks; + + ticks = ( ams * afs_hz )/1000; + + + evp = afs_getevent(event); + + assert_wait((vm_offset_t)(&evp->cond), aintok); + AFS_GUNLOCK(); + thread_set_timeout(ticks); + thread_block(); + AFS_GLOCK(); + /* if (current_thread()->wait_result != THREAD_AWAKENED) + code = EINTR; */ + + relevent(evp); + return code; +} + + +void afs_osi_Wakeup(char *event) +{ + struct afs_event *evp; + + evp = afs_getevent(event); + if (evp->refcount > 1) { + evp->seq++; + thread_wakeup((vm_offset_t)(&evp->cond)); + } + relevent(evp); +} diff --git a/src/afs/NBSD/osi_vfsops.c b/src/afs/NBSD/osi_vfsops.c new file mode 100644 index 000000000..3ab83bb57 --- /dev/null +++ b/src/afs/NBSD/osi_vfsops.c @@ -0,0 +1,485 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +/* + * osi_vfsops.c for DUX + */ +#include +#include "../afs/param.h" + +RCSID("$Header$"); + +#include "../afs/sysincludes.h" /* Standard vendor system headers */ +#include "../afs/afsincludes.h" /* Afs-based standard headers */ +#include "../afs/afs_stats.h" /* statistics stuff */ +#include +#include +#include +#include +#include +#include +#include +#include + + +struct vcache *afs_globalVp = 0; +struct mount *afs_globalVFS = 0; + +static u_char afs_mntid; +int afs_vfsdev = 0; +udecl_simple_lock_data(, afsmntid_lock) +#define AFSMNTID_LOCK() usimple_lock(&afsmntid_lock) +#define AFSMNTID_UNLOCK() usimple_unlock(&afsmntid_lock) +#define AFSMNTID_LOCK_INIT() usimple_lock_init(&afsmntid_lock) + + +int mp_afs_mount(struct mount *afsp,char * path, caddr_t data, + struct nameidata *ndp) +{ + u_int size; + + fsid_t tfsid; + struct mount *xmp, *getvfs(); + int code; + + AFS_GLOCK(); + AFS_STATCNT(afs_mount); + + if (afs_globalVFS) { /* Don't allow remounts. */ + AFS_GUNLOCK(); + return (EBUSY); + } + + afs_globalVFS = afsp; + afsp->vfs_bsize = 8192; +/* + * Generate a unique afs mount i.d. ( see nfs_mount() ). + */ + afsp->m_stat.f_fsid.val[0] = makedev(130, 0); + afsp->m_stat.f_fsid.val[1] = MOUNT_AFS; + AFSMNTID_LOCK(); + if (++afs_mntid == 0) + ++afs_mntid; + AFSMNTID_UNLOCK(); + BM(AFSMNTID_LOCK()); + tfsid.val[0] = makedev(130, afs_mntid); + tfsid.val[1] = MOUNT_AFS; + BM(AFSMNTID_UNLOCK()); + + while (xmp = getvfs(&tfsid)) { + UNMOUNT_READ_UNLOCK(xmp); + tfsid.val[0]++; + AFSMNTID_LOCK(); + afs_mntid++; + AFSMNTID_UNLOCK(); + } + if (major(tfsid.val[0]) != 130) { + AFS_GUNLOCK(); + return (ENOENT); + } + afsp->m_stat.f_fsid.val[0] = tfsid.val[0]; + + afsp->m_stat.f_mntonname = AFS_KALLOC(MNAMELEN); + afsp->m_stat.f_mntfromname = AFS_KALLOC(MNAMELEN); + if ( !afsp->m_stat.f_mntonname || !afsp->m_stat.f_mntfromname) + panic("malloc failure in afs_mount\n"); + + memset(afsp->m_stat.f_mntonname, 0, MNAMELEN); + memset(afsp->m_stat.f_mntfromname, 0, MNAMELEN); + AFS_COPYINSTR(path, (caddr_t)afsp->m_stat.f_mntonname, MNAMELEN, &size, code); + memcpy(afsp->m_stat.f_mntfromname, "AFS", 4); + AFS_GUNLOCK(); + (void) mp_afs_statfs(afsp); + AFS_GLOCK(); + afs_vfsdev = afsp->m_stat.f_fsid.val[0]; + +#ifndef AFS_NONFSTRANS + /* Set up the xlator in case it wasn't done elsewhere */ + afs_xlatorinit_v2(); + afs_xlatorinit_v3(); +#endif + AFS_GUNLOCK(); + return 0; +} + + +int mp_afs_unmount (struct mount *afsp, int flag) +{ + AFS_GLOCK(); + AFS_STATCNT(afs_unmount); + afs_globalVFS = 0; + afs_shutdown(); + AFS_GUNLOCK(); + return 0; +} + + +int mp_afs_start(struct mount *mp, int flags) +{ + return(0); +} + +int mp_afs_root (struct mount *afsp, struct vnode **avpp) +{ + register afs_int32 code = 0; + struct vrequest treq; + register struct vcache *tvp=0; + + AFS_GLOCK(); + AFS_STATCNT(afs_root); + if (afs_globalVp && (afs_globalVp->states & CStatd)) { + tvp = afs_globalVp; + } else { + if (!(code = afs_InitReq(&treq, cred)) && + !(code = afs_CheckInit())) { + tvp = afs_GetVCache(&afs_rootFid, &treq, (afs_int32 *)0, + (struct vcache*)0, WRITE_LOCK); + /* we really want this to stay around */ + if (tvp) { + afs_globalVp = tvp; + } else + code = ENOENT; + } + } + if (tvp) { + AFS_GUNLOCK(); + VN_HOLD((struct vnode *)tvp); + VN_LOCK((struct vnode *)tvp); + tvp->v.v_flag |= VROOT; /* No-op on Ultrix 2.2 */ + VN_UNLOCK((struct vnode *)tvp); + AFS_GLOCK(); + + afs_globalVFS = afsp; + *avpp = (struct vnode *) tvp; + } + + afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp, + ICL_TYPE_INT32, code); + AFS_GUNLOCK(); + return code; +} + + +mp_afs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg) +{ + return EOPNOTSUPP; +} + +int mp_afs_statfs(struct mount *afsp) +{ + struct nstatfs *abp = &afsp->m_stat; + + AFS_GLOCK(); + AFS_STATCNT(afs_statfs); + + abp->f_type = MOUNT_AFS; + abp->f_bsize = afsp->vfs_bsize; + + /* Fake a high number below to satisfy programs that use the statfs call + * to make sure that there's enough space in the device partition before + * storing something there. + */ + abp->f_blocks = abp->f_bfree = abp->f_bavail = abp->f_files = + abp->f_ffree = 2000000; + abp->f_fsize = 1024; + + abp->f_fsid.val[0] = afsp->m_stat.f_fsid.val[0]; + abp->f_fsid.val[1] = afsp->m_stat.f_fsid.val[1]; + + AFS_GUNLOCK(); + return 0; +} + + +int mp_afs_sync(struct mount *mp, int flags) +{ + AFS_STATCNT(afs_sync); + return 0; +} + + +int mp_afs_fhtovp(struct mount *afsp, struct fid *fidp, struct vnode **avcp) +{ + struct vrequest treq; + register code = 0; + + AFS_GLOCK(); + AFS_STATCNT(afs_vget); + + *avcp = NULL; + + if ((code = afs_InitReq(&treq, cred)) == 0) { + code = afs_osi_vget((struct vcache**)avcp, fidp, &treq); + } + + afs_Trace3(afs_iclSetp, CM_TRACE_VGET, ICL_TYPE_POINTER, *avcp, + ICL_TYPE_INT32, treq.uid, ICL_TYPE_FID, fidp); + + code = afs_CheckCode(code, &treq, 42); + AFS_GUNLOCK(); + return code; +} + + +/* + * afs_vptofh + * + * afs_vptofh can return two flavors of NFS fid, depending on if submounts are + * allowed. The reason for this is that we can't guarantee that we found all + * the entry points any OS might use to get the fid for the NFS mountd. + * Hence we return a "magic" fid for all but /afs. If it goes through the + * translator code, it will get transformed into a SmallFid that we recognize. + * So, if submounts are disallowed, and an NFS client tries a submount, it will + * get a fid which we don't recognize and the mount will either fail or we + * will ignore subsequent requests for that mount. + * + * The Alpha fid is organized differently than for other platforms. Their + * intention was to have the data portion of the fid aligned on a 4 byte + * boundary. To do so, the fid is organized as: + * u_short reserved + * u_short len + * char data[8] + * The len field is the length of the entire fid, from reserved through data. + * This length is used by fid_copy to include copying the reserved field. + * Alpha's zero the reserved field before handing us the fid, but they use + * it in fid_cmp. We use the reserved field to store the 16 bits of the Vnode. + * + * Note that the SmallFid only allows for 8 bits of the cell index and + * 16 bits of the vnode. + */ + +#define AFS_FIDDATASIZE 8 +#define AFS_SIZEOFSMALLFID 12 /* full size of fid, including len field */ +extern int afs_NFSRootOnly; /* 1 => only allow NFS mounts of /afs. */ +int afs_fid_vnodeoverflow=0, afs_fid_uniqueoverflow=0; + +int mp_afs_vptofh(struct vnode *avn, struct fid *fidp) +{ + struct SmallFid Sfid; + long addr[2]; + register struct cell *tcell; + int rootvp = 0; + struct vcache *avc = (struct vcache *)avn; + + AFS_GLOCK(); + AFS_STATCNT(afs_fid); + + if (afs_shuttingdown) { + AFS_GUNLOCK(); + return EIO; + } + + if (afs_NFSRootOnly && (avc == afs_globalVp)) rootvp = 1; + if (!afs_NFSRootOnly || rootvp) { + tcell = afs_GetCell(avc->fid.Cell, READ_LOCK); + Sfid.Volume = avc->fid.Fid.Volume; + fidp->fid_reserved = avc->fid.Fid.Vnode; + Sfid.CellAndUnique = ((tcell->cellIndex << 24) + + (avc->fid.Fid.Unique & 0xffffff)); + afs_PutCell(tcell, READ_LOCK); + if (avc->fid.Fid.Vnode > 0xffff) + afs_fid_vnodeoverflow++; + if (avc->fid.Fid.Unique > 0xffffff) + afs_fid_uniqueoverflow++; + } else { + fidp->fid_reserved = AFS_XLATOR_MAGIC; + addr[0] = (long)avc; + AFS_GUNLOCK(); + VN_HOLD((struct vnode *)avc); + AFS_GLOCK(); + } + + /* Use the fid pointer passed to us. */ + fidp->fid_len = AFS_SIZEOFSMALLFID; + if (afs_NFSRootOnly) { + if (rootvp) { + memcpy(fidp->fid_data, (caddr_t)&Sfid, AFS_FIDDATASIZE); + } else { + memcpy(fidp->fid_data, (caddr_t)addr, AFS_FIDDATASIZE); + } + } else { + memcpy(fidp->fid_data, (caddr_t)&Sfid, AFS_FIDDATASIZE); + } + AFS_GUNLOCK(); + return 0; +} + + +int mp_Afs_init(void); /* vfs_init - defined below */ + + +/* This is only called by vfs_mount when afs is going to be mounted as root. + * Since we don't support diskless clients we shouldn't come here. + */ +int afsmountroot=0; +int mp_afs_mountroot(struct mount *afsp, struct vnode **vp) +{ + AFS_GLOCK(); + AFS_STATCNT(afs_mountroot); + afsmountroot++; + AFS_GUNLOCK(); + return EINVAL; +} + + +/* It's called to setup swapping over the net for diskless clients; again + * not for us. + */ +int afsswapvp=0; +int mp_afs_swapvp(void) +{ + AFS_GLOCK(); + AFS_STATCNT(afs_swapvp); + afsswapvp++; + AFS_GUNLOCK(); + return EINVAL; +} + + +struct vfsops afs_vfsops = { + mp_afs_mount, + mp_afs_start, + mp_afs_unmount, + mp_afs_root, + mp_afs_quotactl, + mp_afs_statfs, + mp_afs_sync, + mp_afs_fhtovp, /* afs_vget */ + mp_afs_vptofh, + mp_Afs_init, + mp_afs_mountroot, + mp_afs_swapvp +}; + + +/* + * System Call Entry Points + */ +#define NULL_FUNC (int (*)(int))0 + +int (*afs_syscall_func)() = NULL_FUNC; +int (*afs_xsetgroups_func)() = NULL_FUNC; +int (*afs_xioctl_func)() = NULL_FUNC; + +afssyscall(p, args, retval) + struct proc *p; + void *args; + long *retval; +{ + int (*func)(); + int code; + + AFS_GLOCK(); + func = afs_syscall_func; + if (func == NULL_FUNC) { + code = nosys(p, args, retval); + } else { + code = (*func)(p, args, retval); + } + AFS_GUNLOCK(); + return code; +} + +afsxsetgroups(p, args, retval) + struct proc *p; + void *args; + long *retval; +{ + int (*func)(); + int code; + + AFS_GLOCK(); + func = afs_xsetgroups_func; + if (func == NULL_FUNC) { + code = nosys(p, args, retval); + } else { + code = (*func)(p, args, retval); + } + AFS_GUNLOCK(); + return code; +} + +afsxioctl(p, args, retval) + struct proc *p; + void *args; + long *retval; +{ + int (*func)(); + int code; + + AFS_GLOCK(); + func = afs_xioctl_func; + if (func == NULL_FUNC) { + code = nosys(p, args, retval); + } else { + code = (*func)(p, args, retval); + } + AFS_GUNLOCK(); + return code; +} + + +/* + * VFS initialization and unload + */ + +afs_unconfig() +{ + return EBUSY; +} + + +cfg_subsys_attr_t afs_attributes[] = { + {"", 0, 0, 0, 0, 0, 0} /* must be the last element */ +}; + +afs_configure(cfg_op_t op, caddr_t indata, size_t indata_size, caddr_t outdata, size_t outdata_size) +{ + cfg_attr_t *attributes; + int ret = ESUCCESS; + int i, j, size; + caddr_t p; + + switch (op) { + case CFG_OP_CONFIGURE: + /* + * The indata parameter is a list of attributes to be configured, and + * indata_size is the count of attributes. + */ + if ((ret = vfssw_add_fsname(MOUNT_AFS, &afs_vfsops, "afs")) != 0) + return(ret); + break; + case CFG_OP_UNCONFIGURE: + if ((ret = afs_unconfig()) != 0) + return(ret); + break; + default: + ret = EINVAL; + break; + } + return ret; +} + + +int mp_Afs_init(void) +{ + extern int Afs_xsetgroups(), afs_xioctl(), afs3_syscall(); + + AFS_GLOCK(); + sysent[AFS_SYSCALL].sy_call = afs3_syscall; + sysent[AFS_SYSCALL].sy_parallel = 0; + sysent[AFS_SYSCALL].sy_narg = 6; + sysent[SYS_setgroups].sy_call = Afs_xsetgroups; + afs_xioctl_func = afsxioctl; + afs_xsetgroups_func = afsxsetgroups; + afs_syscall_func = afssyscall; + AFS_GUNLOCK(); + + return 0; +} diff --git a/src/afs/NBSD/osi_vm.c b/src/afs/NBSD/osi_vm.c new file mode 100644 index 000000000..560dfd556 --- /dev/null +++ b/src/afs/NBSD/osi_vm.c @@ -0,0 +1,214 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + + +/* osi_vm.c implements: + * + * osi_VM_FlushVCache(avc, slept) + * osi_ubc_flush_dirty_and_wait(vp, flags) + * osi_VM_StoreAllSegments(avc) + * osi_VM_TryToSmush(avc, acred, sync) + * osi_VM_FlushPages(avc, credp) + * osi_VM_Truncate(avc, alen, acred) + */ + +#include +#include "../afs/param.h" + +RCSID("$Header$"); + +#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. + * + * We also make some sanity checks: ref count, open count, held locks. + * + * We also do some non-VM-related chores, such as releasing the cred pointer + * (for AIX and Solaris) and releasing the gnode (for AIX). + * + * Locking: afs_xvcache lock is held. If it is dropped and re-acquired, + * *slept should be set to warn the caller. + * + * Formerly, afs_xvcache was dropped and re-acquired for Solaris, but now it + * is not dropped and re-acquired for any platform. It may be that *slept is + * therefore obsolescent. + * + * OSF/1 Locking: VN_LOCK has been called. + */ +int +osi_VM_FlushVCache(avc, slept) + struct vcache *avc; + int *slept; +{ +#ifdef SECRETLY_OSF1 + if (avc->vrefCount > 1) + return EBUSY; + + if (avc->opens) + return EBUSY; + + /* if a lock is held, give up */ + if (CheckLock(&avc->lock) || afs_CheckBozonLock(&avc->pvnLock)) + return EBUSY; + + AFS_GUNLOCK(); + ubc_invalidate(((struct vnode *)avc)->v_object, 0, 0, B_INVAL); + AFS_GLOCK(); +#endif /* SECRETLY_OSF1 */ + + return 0; +} + +/* + * osi_ubc_flush_dirty_and_wait -- ensure all dirty pages cleaned + * + * Alpha OSF/1 doesn't make it easy to wait for all dirty pages to be cleaned. + * NFS tries to do this by calling waitforio(), which waits for v_numoutput + * to go to zero. But that isn't good enough, because afs_putpage() doesn't + * increment v_numoutput until it has obtained the vcache entry lock. Suppose + * that Process A, trying to flush a page, is waiting for that lock, and + * Process B tries to close the file. Process B calls waitforio() which thinks + * that everything is cool because v_numoutput is still zero. Process B then + * proceeds to call afs_StoreAllSegments(). Finally when B is finished, A gets + * to proceed and flush its page. But then it's too late because the file is + * already closed. + * + * (I suspect that waitforio() is not adequate for NFS, just as it isn't + * adequate for us. But that's not my problem.) + * + * The only way we can be sure that there are no more dirty pages is if there + * are no more pages with pg_busy set. We look for them on the cleanpl. + * + * For some reason, ubc_flush_dirty() only looks at the dirtypl, not the + * dirtywpl. I don't know why this is good enough, but I assume it is. By + * the same token, I only look for busy pages on the cleanpl, not the cleanwpl. + * + * Called with the global lock NOT held. + */ +void +osi_ubc_flush_dirty_and_wait(vp, flags) +struct vnode *vp; +int flags; { + int retry; + vm_page_t pp; + int first; + +#ifdef SECRETLY_OSF1 + do { + struct vm_ubc_object* vop; + vop = (struct vm_ubc_object*)(vp->v_object); + ubc_flush_dirty(vop, flags); + + vm_object_lock(vop); + if (vop->vu_dirtypl) + /* shouldn't happen, but who knows */ + retry = 1; + else { + retry = 0; + if (vop->vu_cleanpl) { + for (first = 1, pp = vop->vu_cleanpl; + first || pp != vop->vu_cleanpl; + first = 0, pp = pp->pg_onext) { + if (pp->pg_busy) { + retry = 1; + pp->pg_wait = 1; + assert_wait_mesg((vm_offset_t)pp, FALSE, "pg_wait"); + vm_object_unlock(vop); + thread_block(); + break; + } + } + } + if (retry) continue; + } + vm_object_unlock(vop); + } while (retry); +#endif /* SECRETLY_OSF1 */ +} + +/* Try to store pages to cache, in order to store a file back to the server. + * + * Locking: the vcache entry's lock is held. It will usually be dropped and + * re-obtained. + */ +void +osi_VM_StoreAllSegments(avc) + struct vcache *avc; +{ +#ifdef SECRETLY_OSF1 + ReleaseWriteLock(&avc->lock); + AFS_GUNLOCK(); + osi_ubc_flush_dirty_and_wait((struct vnode *)avc, 0); + AFS_GLOCK(); + ObtainWriteLock(&avc->lock,94); +#endif /* SECRETLY_OSF1 */ +} + +/* Try to invalidate pages, for "fs flush" or "fs flushv"; or + * try to free pages, when deleting a file. + * + * Locking: the vcache entry's lock is held. It may be dropped and + * re-obtained. + * + * Since we drop and re-obtain the lock, we can't guarantee that there won't + * be some pages around when we return, newly created by concurrent activity. + */ +void +osi_VM_TryToSmush(avc, acred, sync) + struct vcache *avc; + struct AFS_UCRED *acred; + int sync; +{ +#ifdef SECRETLY_OSF1 + ReleaseWriteLock(&avc->lock); + AFS_GUNLOCK(); + osi_ubc_flush_dirty_and_wait((struct vnode *)avc, 0); + ubc_invalidate(((struct vnode *)avc)->v_object, 0, 0, B_INVAL); + AFS_GLOCK(); + ObtainWriteLock(&avc->lock,59); +#endif /* SECRETLY_OSF1 */ +} + +/* Purge VM for a file when its callback is revoked. + * + * Locking: No lock is held, not even the global lock. + */ +void +osi_VM_FlushPages(avc, credp) + struct vcache *avc; + struct AFS_UCRED *credp; +{ +#ifdef SECRETLY_OSF1 + ubc_flush_dirty(((struct vnode *)avc)->v_object, 0); + ubc_invalidate(((struct vnode *)avc)->v_object, 0, 0, B_INVAL); +#endif /* SECRETLY_OSF1 */ +} + +/* Purge pages beyond end-of-file, when truncating a file. + * + * Locking: no lock is held, not even the global lock. + * activeV is raised. This is supposed to block pageins, but at present + * it only works on Solaris. + */ +void +osi_VM_Truncate(avc, alen, acred) + struct vcache *avc; + int alen; + struct AFS_UCRED *acred; +{ +#ifdef SECRETLY_OSF1 + ubc_invalidate(((struct vnode *)avc)->v_object, alen, + MAXINT - alen, B_INVAL); +#endif /* SECRETLY_OSF1 */ +} diff --git a/src/afs/NBSD/osi_vnodeops.c b/src/afs/NBSD/osi_vnodeops.c new file mode 100644 index 000000000..beacd6999 --- /dev/null +++ b/src/afs/NBSD/osi_vnodeops.c @@ -0,0 +1,1095 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +/* + * vnodeops structure and Digital Unix specific ops and support routines. + */ + +#include +#include "../afs/param.h" + +RCSID("$Header$"); + + +#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 +/* #include */ +#include "../afs/afs_cbqueue.h" +#include "../afs/nfsclient.h" +#include "../afs/afs_osidnlc.h" + + +extern int afs_lookup(), afs_create(), afs_noop(), afs_open(), afs_close(); +extern int afs_access(), afs_getattr(), afs_setattr(), afs_badop(); +extern int afs_fsync(), afs_seek(), afs_remove(), afs_link(), afs_rename(); +extern int afs_mkdir(), afs_rmdir(), afs_symlink(), afs_readdir(); +extern int afs_readlink(), afs_lockctl(); +extern int vn_pathconf_default(), seltrue(); + +int mp_afs_lookup(), mp_afs_create(), mp_afs_open(); +int mp_afs_access(), mp_afs_getattr(), mp_afs_setattr(), mp_afs_ubcrdwr(); +int mp_afs_ubcrdwr(), mp_afs_mmap(); +int mp_afs_fsync(), mp_afs_seek(), mp_afs_remove(), mp_afs_link(); +int mp_afs_rename(), mp_afs_mkdir(), mp_afs_rmdir(), mp_afs_symlink(); +int mp_afs_readdir(), mp_afs_readlink(), mp_afs_abortop(), mp_afs_inactive(); +int mp_afs_reclaim(), mp_afs_bmap(), mp_afs_strategy(), mp_afs_print(); +int mp_afs_page_read(), mp_afs_page_write(), mp_afs_swap(), mp_afs_bread(); +int mp_afs_brelse(), mp_afs_lockctl(), mp_afs_syncdata(), mp_afs_close(); +int mp_afs_closex(); + +#if 0 +/* AFS vnodeops */ +struct vnodeops Afs_vnodeops = { + mp_afs_lookup, + mp_afs_create, + afs_noop, /* vn_mknod */ + mp_afs_open, + mp_afs_close, + mp_afs_access, + mp_afs_getattr, + mp_afs_setattr, + mp_afs_ubcrdwr, + mp_afs_ubcrdwr, + afs_badop, /* vn_ioctl */ + seltrue, /* vn_select */ + mp_afs_mmap, + mp_afs_fsync, + mp_afs_seek, + mp_afs_remove, + mp_afs_link, + mp_afs_rename, + mp_afs_mkdir, + mp_afs_rmdir, + mp_afs_symlink, + mp_afs_readdir, + mp_afs_readlink, + mp_afs_abortop, + mp_afs_inactive, + mp_afs_reclaim, + mp_afs_bmap, + mp_afs_strategy, + mp_afs_print, + mp_afs_page_read, + mp_afs_page_write, + mp_afs_swap, + mp_afs_bread, + mp_afs_brelse, + mp_afs_lockctl, + mp_afs_syncdata, + afs_noop, /* Lock */ + afs_noop, /* unLock */ + afs_noop, /* get ext attrs */ + afs_noop, /* set ext attrs */ + afs_noop, /* del ext attrs */ + vn_pathconf_default, +}; +struct vnodeops *afs_ops = &Afs_vnodeops; +#endif /* 0 */ + +/* vnode file operations, and our own */ +extern int vn_read(); +extern int vn_write(); +extern int vn_ioctl(); +extern int vn_select(); +extern int afs_closex(); + +struct fileops afs_fileops = { + vn_read, + vn_write, + vn_ioctl, + vn_select, + mp_afs_closex, +}; + +#if 0 +mp_afs_lookup(adp, ndp) + struct vcache *adp; + struct nameidata *ndp; +{ + int code; + AFS_GLOCK(); + code = afs_lookup(adp, ndp); + AFS_GUNLOCK(); + return code; +} + +mp_afs_create(ndp, attrs) + struct nameidata *ndp; + struct vattr *attrs; +{ + int code; + AFS_GLOCK(); + code = afs_create(ndp, attrs); + AFS_GUNLOCK(); + return code; +} + +mp_afs_open(avcp, aflags, acred) + struct vcache **avcp; + afs_int32 aflags; + struct AFS_UCRED *acred; +{ + int code; + AFS_GLOCK(); + code = afs_open(avcp, aflags, acred); + AFS_GUNLOCK(); + return code; +} + +mp_afs_access(avc, amode, acred) + struct vcache *avc; + afs_int32 amode; + struct AFS_UCRED *acred; +{ + int code; + AFS_GLOCK(); + code = afs_access(avc, amode, acred); + AFS_GUNLOCK(); + return code; +} + +mp_afs_close(avc, flags, cred) + struct vnode *avc; + int flags; + struct ucred *cred; +{ + int code; + AFS_GLOCK(); + code = afs_close(avc, flags, cred); + AFS_GUNLOCK(); + return code; +} + +mp_afs_getattr(avc, attrs, acred) + struct vcache *avc; + struct vattr *attrs; + struct AFS_UCRED *acred; +{ + int code; + AFS_GLOCK(); + code = afs_getattr(avc, attrs, acred); + AFS_GUNLOCK(); + return code; +} + +mp_afs_setattr(avc, attrs, acred) + struct vcache *avc; + struct vattr *attrs; + struct AFS_UCRED *acred; +{ + int code; + AFS_GLOCK(); + code = afs_setattr(avc, attrs, acred); + AFS_GUNLOCK(); + return code; +} + +mp_afs_fsync(avc, fflags, acred, waitfor) + struct vcache *avc; + int fflags; + struct AFS_UCRED *acred; + int waitfor; +{ + int code; + AFS_GLOCK(); + code = afs_fsync(avc, fflags, acred, waitfor); + AFS_GUNLOCK(); + return code; +} + +mp_afs_remove(ndp) + struct nameidata *ndp; +{ + int code; + AFS_GLOCK(); + code = afs_remove(ndp); + AFS_GUNLOCK(); + return code; +} + +mp_afs_link(avc, ndp) + struct vcache *avc; + struct nameidata *ndp; +{ + int code; + AFS_GLOCK(); + code = afs_link(avc, ndp); + AFS_GUNLOCK(); + return code; +} + +mp_afs_rename(fndp, tndp) + struct nameidata *fndp, *tndp; +{ + int code; + AFS_GLOCK(); + code = afs_rename(fndp, tndp); + AFS_GUNLOCK(); + return code; +} + +mp_afs_mkdir(ndp, attrs) + struct nameidata *ndp; + struct vattr *attrs; +{ + int code; + AFS_GLOCK(); + code = afs_mkdir(ndp, attrs); + AFS_GUNLOCK(); + return code; +} + +mp_afs_rmdir(ndp) + struct nameidata *ndp; +{ + int code; + AFS_GLOCK(); + code = afs_rmdir(ndp); + AFS_GUNLOCK(); + return code; +} + +mp_afs_symlink(ndp, attrs, atargetName) + struct nameidata *ndp; + struct vattr *attrs; + register char *atargetName; +{ + int code; + AFS_GLOCK(); + code = afs_symlink(ndp, attrs, atargetName); + AFS_GUNLOCK(); + return code; +} + +mp_afs_readdir(avc, auio, acred, eofp) + struct vcache *avc; + struct uio *auio; + struct AFS_UCRED *acred; + int *eofp; +{ + int code; + AFS_GLOCK(); + code = afs_readdir(avc, auio, acred, eofp); + AFS_GUNLOCK(); + return code; +} + +mp_afs_readlink(avc, auio, acred) + struct vcache *avc; + struct uio *auio; + struct AFS_UCRED *acred; +{ + int code; + AFS_GLOCK(); + code = afs_readlink(avc, auio, acred); + AFS_GUNLOCK(); + return code; +} + +mp_afs_lockctl(avc, af, flag, acred, clid, offset) + struct vcache *avc; + struct eflock *af; + struct AFS_UCRED *acred; + int flag; + pid_t clid; + off_t offset; +{ + int code; + AFS_GLOCK(); + code = afs_lockctl(avc, af, flag, acred, clid, offset); + AFS_GUNLOCK(); + return code; +} + +mp_afs_closex(afd) + struct file *afd; +{ + int code; + AFS_GLOCK(); + code = afs_closex(afd); + AFS_GUNLOCK(); + return code; +} + +mp_afs_seek(avc, oldoff, newoff, cred) + struct vcache *avc; + off_t oldoff, newoff; + struct ucred *cred; +{ + if ((int) newoff < 0) + return(EINVAL); + else + return(0); +} + +mp_afs_abortop(ndp) + struct nameidata *ndp; +{ + return(0); +} + +mp_afs_inactive(avc, acred) + register struct vcache *avc; + struct AFS_UCRED *acred; +{ + AFS_GLOCK(); + afs_InactiveVCache(avc, acred); + AFS_GUNLOCK(); +} + + +mp_afs_reclaim(avc) + struct vcache *avc; +{ + return(0); +} + +mp_afs_print(avc) + struct vcache *avc; +{ + return(0); +} + +mp_afs_page_read(avc, uio, acred) + struct vcache *avc; + struct uio *uio; + struct ucred *acred; +{ + int error; + struct vrequest treq; + + AFS_GLOCK(); + error = afs_rdwr(avc, uio, UIO_READ, 0, acred); + afs_Trace3(afs_iclSetp, CM_TRACE_PAGE_READ, ICL_TYPE_POINTER, avc, + ICL_TYPE_INT32, error, ICL_TYPE_INT32, avc->states); + if (error) { + error = EIO; + } else if ((avc->states) == 0) { + afs_InitReq(&treq, acred); + ObtainWriteLock(&avc->lock,161); + afs_Wire(avc, &treq); + ReleaseWriteLock(&avc->lock); + } + AFS_GUNLOCK(); + return(error); +} + + +mp_afs_page_write(avc, uio, acred, pager, offset) + struct vcache *avc; + struct uio *uio; + struct ucred *acred; + memory_object_t pager; + vm_offset_t offset; +{ + int error; + + AFS_GLOCK(); + error = afs_rdwr(avc, uio, UIO_WRITE, 0, acred); + afs_Trace3(afs_iclSetp, CM_TRACE_PAGE_WRITE, ICL_TYPE_POINTER, avc, + ICL_TYPE_INT32, error, ICL_TYPE_INT32, avc->states); + if (error) { + error = EIO; + } + AFS_GUNLOCK(); + return(error); +} + + +int DO_FLUSH=1; +mp_afs_ubcrdwr(avc, uio, ioflag, cred) + struct vcache *avc; + struct uio *uio; + int ioflag; + struct ucred *cred; +{ + register afs_int32 code; + register char *data; + afs_int32 fileBase, size, cnt=0; + afs_int32 pageBase; + register afs_int32 tsize; + register afs_int32 pageOffset; + int eof; + struct vrequest treq; + int rw = uio->uio_rw; + int rv, flags; + int newpage=0; + vm_page_t page; + afs_int32 save_resid; + struct dcache *tdc; + int didFakeOpen=0; + int counter=0; + + AFS_GLOCK(); + afs_InitReq(&treq, cred); + if (AFS_NFSXLATORREQ(cred) && rw == UIO_READ) { + if (!afs_AccessOK(avc, PRSFS_READ, &treq, + CHECK_MODE_BITS|CMB_ALLOW_EXEC_AS_READ)) { + AFS_GUNLOCK(); + return EACCES; + } + } + afs_Trace4(afs_iclSetp, CM_TRACE_VMRW, ICL_TYPE_POINTER, avc, + ICL_TYPE_INT32, (rw==UIO_WRITE? 1 : 0), + ICL_TYPE_LONG, uio->uio_offset, + ICL_TYPE_LONG, uio->uio_resid); + code = afs_VerifyVCache(avc, &treq); + if (code) { + code = afs_CheckCode(code, &treq, 35); + AFS_GUNLOCK(); + return code; + } + if (vType(avc) != VREG) { + AFS_GUNLOCK(); + return EISDIR; /* can't read or write other things */ + } + afs_BozonLock(&avc->pvnLock, avc); + osi_FlushPages(avc); /* hold bozon lock, but not basic vnode lock */ + ObtainWriteLock(&avc->lock,162); + /* adjust parameters when appending files */ + if ((ioflag & IO_APPEND) && uio->uio_rw == UIO_WRITE) + uio->uio_offset = avc->m.Length; /* write at EOF position */ + if (uio->uio_rw == UIO_WRITE) { + avc->states |= CDirty; + afs_FakeOpen(avc); + didFakeOpen=1; + /* + * before starting any I/O, we must ensure that the file is big enough + * to hold the results (since afs_putpage will be called to force + * the I/O. + */ + size = uio->afsio_resid + uio->afsio_offset; /* new file size */ + if (size > avc->m.Length) avc->m.Length = size; /* file grew */ + avc->m.Date = osi_Time(); /* Set file date (for ranlib) */ + if (uio->afsio_resid > PAGE_SIZE) + cnt = uio->afsio_resid / PAGE_SIZE; + save_resid = uio->afsio_resid; + } + + while (1) { + /* + * compute the amount of data to move into this block, + * based on uio->afsio_resid. + */ + size = uio->afsio_resid; /* transfer size */ + fileBase = uio->afsio_offset; /* start file position */ + pageBase = fileBase & ~(PAGE_SIZE-1); /* file position of the page */ + pageOffset = fileBase & (PAGE_SIZE-1); /* start offset within page */ + tsize = PAGE_SIZE-pageOffset; /* amount left in this page */ + /* + * we'll read tsize bytes, + * but first must make sure tsize isn't too big + */ + if (tsize > size) tsize = size; /* don't read past end of request */ + eof = 0; /* flag telling us if we hit the EOF on the read */ + if (uio->uio_rw == UIO_READ) { /* we're doing a read operation */ + /* don't read past EOF */ + if (tsize + fileBase > avc->m.Length) { + tsize = avc->m.Length - fileBase; + eof = 1; /* we did hit the EOF */ + if (tsize < 0) tsize = 0; /* better safe than sorry */ + } + } + if (tsize <= 0) break; /* nothing to transfer, we're done */ + + /* Purge dirty chunks of file if there are too many dirty chunks. + * Inside the write loop, we only do this at a chunk boundary. + * Clean up partial chunk if necessary at end of loop. + */ + if (uio->uio_rw == UIO_WRITE && counter > 0 + && AFS_CHUNKOFFSET(fileBase) == 0) { + code = afs_DoPartialWrite(avc, &treq); + avc->states |= CDirty; + } + + if (code) { + break; + } + + flags = 0; + ReleaseWriteLock(&avc->lock); + AFS_GUNLOCK(); + code = ubc_lookup(((struct vnode *)avc)->v_object, pageBase, + PAGE_SIZE, PAGE_SIZE, &page, &flags); + AFS_GLOCK(); + ObtainWriteLock(&avc->lock,163); + + if (code) { + break; + } + if (flags & B_NOCACHE) { + /* + No page found. We should not read the page in if + 1. the write starts on a page edge (ie, pageoffset == 0) + and either + 1. we will fill the page (ie, size == PAGESIZE), or + 2. we are writing past eof + */ + if ((uio->uio_rw == UIO_WRITE) && + ((pageOffset == 0 && (size == PAGE_SIZE || fileBase >= avc->m.Length)))) { + struct vnode *vp = (struct vnode *)avc; + /* we're doing a write operation past eof; no need to read it */ + newpage = 1; + AFS_GUNLOCK(); + ubc_page_zero(page, 0, PAGE_SIZE); + ubc_page_release(page, B_DONE); + AFS_GLOCK(); + } else { + /* page wasn't cached, read it in. */ + struct buf *bp; + + AFS_GUNLOCK(); + bp = ubc_bufalloc(page, 1, PAGE_SIZE, 1, B_READ); + AFS_GLOCK(); + bp->b_dev = 0; + bp->b_vp = (struct vnode *)avc; + bp->b_blkno = btodb(pageBase); + ReleaseWriteLock(&avc->lock); + code = afs_ustrategy(bp, cred); /* do the I/O */ + ObtainWriteLock(&avc->lock,164); + AFS_GUNLOCK(); + ubc_sync_iodone(bp); + AFS_GLOCK(); + if (code) { + AFS_GUNLOCK(); + ubc_page_release(page, 0); + AFS_GLOCK(); + break; + } + } + } + AFS_GUNLOCK(); + ubc_page_wait(page); + data = (char *)page->pg_addr; /* DUX 4.0D */ + if (data == 0) + data = (char *)PHYS_TO_KSEG(page->pg_phys_addr); /* DUX 4.0E */ + AFS_GLOCK(); + ReleaseWriteLock(&avc->lock); /* uiomove may page fault */ + AFS_GUNLOCK(); + code = uiomove(data+pageOffset, tsize, uio); + ubc_unload(page, pageOffset, page_size); + if (uio->uio_rw == UIO_WRITE) { + vm_offset_t toffset; + + /* Mark the page dirty and release it to avoid a deadlock + * in ubc_dirty_kluster when more than one process writes + * this page at the same time. */ + toffset = page->pg_offset; + flags |= B_DIRTY; + ubc_page_release(page, flags); + + if (cnt > 10) { + vm_page_t pl; + int kpcnt; + struct buf *bp; + + /* We released the page, so we can get a null page + * list if another thread calls the strategy routine. + */ + pl = ubc_dirty_kluster(((struct vnode *)avc)->v_object, + NULL, toffset, 0, B_WANTED, FALSE, &kpcnt); + if (pl) { + bp = ubc_bufalloc(pl, 1, PAGE_SIZE, 1, B_WRITE); + bp->b_dev = 0; + bp->b_vp = (struct vnode *)avc; + bp->b_blkno = btodb(pageBase); + AFS_GLOCK(); + code = afs_ustrategy(bp, cred); /* do the I/O */ + AFS_GUNLOCK(); + ubc_sync_iodone(bp); + if (code) { + AFS_GLOCK(); + ObtainWriteLock(&avc->lock,415); + break; + } + } + } + } else { + ubc_page_release(page, flags); + } + AFS_GLOCK(); + ObtainWriteLock(&avc->lock,165); + /* + * If reading at a chunk boundary, start prefetch of next chunk. + */ + if (uio->uio_rw == UIO_READ + && (counter == 0 || AFS_CHUNKOFFSET(fileBase) == 0)) { + tdc = afs_FindDCache(avc, fileBase); + if (tdc) { + if (!(tdc->mflags & DFNextStarted)) + afs_PrefetchChunk(avc, tdc, cred, &treq); + afs_PutDCache(tdc); + } + } + counter++; + if (code) break; + } + if (didFakeOpen) + afs_FakeClose(avc, cred); + if (uio->uio_rw == UIO_WRITE && code == 0 && (avc->states & CDirty)) { + code = afs_DoPartialWrite(avc, &treq); + } + ReleaseWriteLock(&avc->lock); + afs_BozonUnlock(&avc->pvnLock, avc); + if (DO_FLUSH || (!newpage && (cnt < 10))) { + AFS_GUNLOCK(); + ubc_flush_dirty(((struct vnode *)avc)->v_object, flags); + AFS_GLOCK(); + } + + ObtainSharedLock(&avc->lock, 409); + if (!code) { + if (avc->vc_error) { + code = avc->vc_error; + } + } + /* This is required since we may still have dirty pages after the write. + * I could just let close do the right thing, but stat's before the close + * return the wrong length. + */ + if (code == EDQUOT || code == ENOSPC) { + uio->uio_resid = save_resid; + UpgradeSToWLock(&avc->lock, 410); + osi_ReleaseVM(avc, cred); + ConvertWToSLock(&avc->lock); + } + ReleaseSharedLock(&avc->lock); + + if (!code && (ioflag & IO_SYNC) && (uio->uio_rw == UIO_WRITE) + && !AFS_NFSXLATORREQ(cred)) { + code = afs_fsync(avc, 0, cred, 0); + } +out: + code = afs_CheckCode(code, &treq, 36); + AFS_GUNLOCK(); + return code; +} + + +/* + * Now for some bad news. Since we artificially hold on to vnodes by doing + * and extra VNHOLD in afs_NewVCache(), there is no way for us to know + * when we need to flush the pages when a program exits. Particularly + * if it closes the file after mapping it R/W. + * + */ + +mp_afs_mmap(avc, offset, map, addrp, len, prot, maxprot, flags, cred) + register struct vcache *avc; + vm_offset_t offset; + vm_map_t map; + vm_offset_t *addrp; + vm_size_t len; + vm_prot_t prot; + vm_prot_t maxprot; + int flags; + struct ucred *cred; +{ + struct vp_mmap_args args; + register struct vp_mmap_args *ap = &args; + struct vnode *vp = (struct vnode *)avc; + int code; + struct vrequest treq; +#if !defined(DYNEL) + extern kern_return_t u_vp_create(); +#endif + + AFS_GLOCK(); + afs_InitReq(&treq, cred); + code = afs_VerifyVCache(avc, &treq); + if (code) { + code = afs_CheckCode(code, &treq, 37); + AFS_GUNLOCK(); + return code; + } + afs_BozonLock(&avc->pvnLock, avc); + osi_FlushPages(avc); /* ensure old pages are gone */ + afs_BozonUnlock(&avc->pvnLock, avc); + ObtainWriteLock(&avc->lock,166); + avc->states |= CMAPPED; + ReleaseWriteLock(&avc->lock); + ap->a_offset = offset; + ap->a_vaddr = addrp; + ap->a_size = len; + ap->a_prot = prot, + ap->a_maxprot = maxprot; + ap->a_flags = flags; + AFS_GUNLOCK(); + code = u_vp_create(map, vp->v_object, (vm_offset_t) ap); + AFS_GLOCK(); + code = afs_CheckCode(code, &treq, 38); + AFS_GUNLOCK(); + return code; +} + + +int mp_afs_getpage(vop, offset, len, protp, pl, plsz, mape, addr, rw, cred) + vm_ubc_object_t vop; + vm_offset_t offset; + vm_size_t len; + vm_prot_t *protp; + vm_page_t *pl; + int plsz; + vm_map_entry_t mape; + vm_offset_t addr; + int rw; + struct ucred *cred; +{ + register afs_int32 code; + struct vrequest treq; + int flags = 0; + int i, pages = (len + PAGE_SIZE - 1) >> page_shift; + vm_page_t *pagep; + vm_offset_t off; + + struct vcache *avc = (struct vcache *)vop->vu_vp; + + /* first, obtain the proper lock for the VM system */ + + AFS_GLOCK(); + afs_InitReq(&treq, cred); + code = afs_VerifyVCache(avc, &treq); + if (code) { + *pl = VM_PAGE_NULL; + code = afs_CheckCode(code, &treq, 39); /* failed to get it */ + AFS_GUNLOCK(); + return code; + } + + /* clean all dirty pages for this vnode */ + AFS_GUNLOCK(); + ubc_flush_dirty(vop,0); + AFS_GLOCK(); + + afs_BozonLock(&avc->pvnLock, avc); + ObtainWriteLock(&avc->lock,167); + afs_Trace4(afs_iclSetp, CM_TRACE_PAGEIN, ICL_TYPE_POINTER, avc, + ICL_TYPE_LONG, offset, ICL_TYPE_LONG, len, + ICL_TYPE_INT32, (int) rw); + for (i = 0; i < pages; i++) { + pagep = &pl[i]; + off = offset + PAGE_SIZE * i; + if (protp) protp[i] = 0; + flags = 0; + ReleaseWriteLock(&avc->lock); + AFS_GUNLOCK(); + code = ubc_lookup(((struct vnode *)avc)->v_object, off, + PAGE_SIZE, PAGE_SIZE, pagep, &flags); + AFS_GLOCK(); + ObtainWriteLock(&avc->lock,168); + if (code) { + goto out; + } + if(flags & B_NOCACHE) { /* if (page) */ + if ((rw & B_WRITE) && (offset+len >= avc->m.Length)) { + struct vnode *vp = (struct vnode *)avc; + /* we're doing a write operation past eof; no need to read it */ + AFS_GUNLOCK(); + ubc_page_zero(*pagep, 0, PAGE_SIZE); + ubc_page_release(*pagep, B_DONE); + AFS_GLOCK(); + } else { + /* page wasn't cached, read it in. */ + struct buf *bp; + + AFS_GUNLOCK(); + bp = ubc_bufalloc(*pagep, 1, PAGE_SIZE, 1, B_READ); + AFS_GLOCK(); + bp->b_dev = 0; + bp->b_vp = (struct vnode *)avc; + bp->b_blkno = btodb(off); + ReleaseWriteLock(&avc->lock); + code = afs_ustrategy(bp, cred); /* do the I/O */ + ObtainWriteLock(&avc->lock,169); + AFS_GUNLOCK(); + ubc_sync_iodone(bp); + AFS_GLOCK(); + if (code) { + AFS_GUNLOCK(); + ubc_page_release(pl[i], 0); + AFS_GLOCK(); + goto out; + } + } + } + if ((rw & B_READ) == 0) { + AFS_GUNLOCK(); + ubc_page_dirty(pl[i]); + AFS_GLOCK(); + } else { + if (protp && (flags & B_DIRTY) == 0) { + protp[i] = VM_PROT_WRITE; + } + } + } +out: + pl[i] = VM_PAGE_NULL; + ReleaseWriteLock(&avc->lock); + afs_BozonUnlock(&avc->pvnLock, avc); + afs_Trace3(afs_iclSetp, CM_TRACE_PAGEINDONE, ICL_TYPE_INT32, code, + ICL_TYPE_POINTER, *pagep, ICL_TYPE_INT32, flags); + code = afs_CheckCode(code, &treq, 40); + AFS_GUNLOCK(); + return code; +} + + +int mp_afs_putpage(vop, pl, pcnt, flags, cred) + vm_ubc_object_t vop; + vm_page_t *pl; + int pcnt; + int flags; + struct ucred *cred; +{ + register afs_int32 code=0; + struct vcache *avc = (struct vcache *)vop->vu_vp; + struct vnode *vp = (struct vnode *)avc; + int i; + + AFS_GLOCK(); + afs_Trace4(afs_iclSetp, CM_TRACE_PAGEOUT, ICL_TYPE_POINTER, avc, + ICL_TYPE_INT32, pcnt, ICL_TYPE_INT32, vp->v_flag, + ICL_TYPE_INT32, flags); + if (flags & B_UBC) { + AFS_GUNLOCK(); + VN_LOCK(vp); + if (vp->v_flag & VXLOCK) { + VN_UNLOCK(vp); + for (i = 0; i < pcnt; i++) { + ubc_page_release(pl[i], B_DONE|B_DIRTY); + pl[i] = VM_PAGE_NULL; + } + return(0); + } else { + VN_UNLOCK(vp); + } + AFS_GLOCK(); + } + + /* first, obtain the proper lock for the VM system */ + afs_BozonLock(&avc->pvnLock, avc); + ObtainWriteLock(&avc->lock,170); + for (i = 0; i < pcnt; i++) { + vm_page_t page = pl[i]; + struct buf *bp; + + /* write it out */ + AFS_GUNLOCK(); + bp = ubc_bufalloc(page, 1, PAGE_SIZE, 1, B_WRITE); + AFS_GLOCK(); + bp->b_dev = 0; + bp->b_vp = (struct vnode *)avc; + bp->b_blkno = btodb(page->pg_offset); + ReleaseWriteLock(&avc->lock); + code = afs_ustrategy(bp, cred); /* do the I/O */ + ObtainWriteLock(&avc->lock,171); + AFS_GUNLOCK(); + ubc_sync_iodone(bp); + AFS_GLOCK(); + if (code) { + goto done; + } else { + pl[i] = VM_PAGE_NULL; + } + } +done: + ReleaseWriteLock(&avc->lock); + afs_BozonUnlock(&avc->pvnLock, avc); + afs_Trace2(afs_iclSetp, CM_TRACE_PAGEOUTDONE, ICL_TYPE_INT32, code, + ICL_TYPE_INT32, avc->m.Length); + AFS_GUNLOCK(); + return code; +} + + +int mp_afs_swap(avc, swapop, argp) + struct vcache *avc; + vp_swap_op_t swapop; + vm_offset_t argp; +{ + return EIO; +} + +int mp_afs_syncdata(avc, flag, offset, length, cred) + struct vcache *avc; + int flag; + vm_offset_t offset; + vm_size_t length; + struct ucred *cred; +{ + /* NFS V3 makes this call, ignore it. We'll sync the data in afs_fsync. */ + if (AFS_NFSXLATORREQ(cred)) + return 0; + else + return EINVAL; +} + +/* a freelist of one */ +struct buf *afs_bread_freebp = 0; + +/* + * Only rfs_read calls this, and it only looks at bp->b_un.b_addr. + * Thus we can use fake bufs (ie not from the real buffer pool). + */ +mp_afs_bread(vp, lbn, bpp, cred) + struct ucred *cred; + struct vnode *vp; + daddr_t lbn; + struct buf **bpp; +{ + int offset, fsbsize, error; + struct buf *bp; + struct iovec iov; + struct uio uio; + + AFS_GLOCK(); + AFS_STATCNT(afs_bread); + fsbsize = vp->v_vfsp->vfs_bsize; + offset = lbn * fsbsize; + if (afs_bread_freebp) { + bp = afs_bread_freebp; + afs_bread_freebp = 0; + } else { + bp = (struct buf *) AFS_KALLOC(sizeof(*bp)); + bp->b_un.b_addr = (caddr_t) AFS_KALLOC(fsbsize); + } + + iov.iov_base = bp->b_un.b_addr; + iov.iov_len = fsbsize; + uio.afsio_iov = &iov; + uio.afsio_iovcnt = 1; + uio.afsio_seg = AFS_UIOSYS; + uio.afsio_offset = offset; + uio.afsio_resid = fsbsize; + *bpp = 0; + error = afs_read((struct vcache *)vp, &uio, cred, lbn, bpp, 0); + if (error) { + afs_bread_freebp = bp; + AFS_GUNLOCK(); + return error; + } + if (*bpp) { + afs_bread_freebp = bp; + } else { + *(struct buf **)&bp->b_vp = bp; /* mark as fake */ + *bpp = bp; + } + AFS_GUNLOCK(); + return 0; +} + + +mp_afs_brelse(vp, bp) +struct vnode *vp; +struct buf *bp; +{ + AFS_GLOCK(); + AFS_STATCNT(afs_brelse); + if ((struct buf *)bp->b_vp != bp) { /* not fake */ + brelse(bp); + } else if (afs_bread_freebp) { + AFS_KFREE(bp->b_un.b_addr, vp->v_vfsp->vfs_bsize); + AFS_KFREE(bp, sizeof(*bp)); + } else { + afs_bread_freebp = bp; + } + AFS_GUNLOCK(); +} + + +mp_afs_bmap(avc, abn, anvp, anbn) + register struct vcache *avc; + afs_int32 abn, *anbn; + struct vcache **anvp; +{ + AFS_GLOCK(); + AFS_STATCNT(afs_bmap); + if (anvp) + *anvp = avc; + if (anbn) + *anbn = abn * (8192 / DEV_BSIZE); /* in 512 byte units */ + AFS_GUNLOCK(); + return 0; +} + + +/* real strategy */ +mp_afs_strategy (abp) + register struct buf *abp; +{ + register afs_int32 code; + + AFS_GLOCK(); + AFS_STATCNT(afs_strategy); + code = afs_osi_MapStrategy(afs_ustrategy, abp); + AFS_GUNLOCK(); + return code; +} + + +mp_afs_refer(vm_ubc_object_t vop) +{ + VREF(vop->vu_vp); +} + + +mp_afs_release(vm_ubc_object_t vop) +{ + vrele(vop->vu_vp); +} + + +mp_afs_write_check(vm_ubc_object_t vop, vm_page_t pp) +{ + return TRUE; +} + + + +struct vfs_ubcops afs_ubcops = { + mp_afs_refer, /* refer vnode */ + mp_afs_release, /* release vnode */ + mp_afs_getpage, /* get page */ + mp_afs_putpage, /* put page */ + mp_afs_write_check, /* check writablity */ +}; +#endif /* 0 */ + +/* + * Cover function for lookup name using OSF equivalent, namei() + * + * Note, the result vnode (ni_vp) in the namei data structure is remains + * locked after return. + */ +lookupname(namep, seg, follow, dvpp, cvpp) + char *namep; /* path name */ + int seg; /* address space containing name */ + int follow; /* follow symbolic links */ + struct vnode **dvpp; /* result, containing parent vnode */ + struct vnode **cvpp; /* result, containing final component vnode */ +{ + /* Should I use free-bee in u-area? */ + struct nameidata *ndp = &u.u_nd; + int error; + + ndp->ni_nameiop = ((follow) ? (LOOKUP|FOLLOW) : (LOOKUP)); + ndp->ni_segflg = seg; + ndp->ni_dirp = namep; + error = namei(ndp); + if (dvpp != (struct vnode **)0) + *dvpp = ndp->ni_dvp; + if (cvpp != (struct vnode **)0) + *cvpp = ndp->ni_vp; + return(error); +} + diff --git a/src/cf/osconf.m4 b/src/cf/osconf.m4 index 44eeb331b..062dc4488 100644 --- a/src/cf/osconf.m4 +++ b/src/cf/osconf.m4 @@ -128,6 +128,18 @@ case $AFS_SYSNAME in YACC="bison -y" ;; + i386_nbsd15) + LEX="flex -l" + MT_CFLAGS='${XCFLAGS}' + MT_LIBS="" + PAM_CFLAGS="-O2 -pipe -fPIC" + SHLIB_LDFLAGS="-shared -Xlinker -x" + TXLIBS="/usr/lib/libcurses.so" + XCFLAGS="-O2 -pipe" + XLIBS="${LIB_AFSDB} -lcompat" + YACC="bison -y" + ;; + i386_linux22) LEX="flex -l" MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}' diff --git a/src/config/Makefile.config.in b/src/config/Makefile.config.in index d33eccc06..fa889786e 100644 --- a/src/config/Makefile.config.in +++ b/src/config/Makefile.config.in @@ -8,6 +8,7 @@ afsdbdir=@afsdbdir@ afslocaldir=@afslocaldir@ afslogsdir=@afslogsdir@ afssrvbindir=@afssrvbindir@ +afskerneldir=@afskerneldir@ afssrvlibexecdir=@afssrvlibexecdir@ afssrvsbindir=@afssrvsbindir@ bindir=@bindir@ diff --git a/src/config/param.i386_nbsd15.h b/src/config/param.i386_nbsd15.h new file mode 100644 index 000000000..4c3d916df --- /dev/null +++ b/src/config/param.i386_nbsd15.h @@ -0,0 +1,110 @@ +#ifndef AFS_PARAM_H +#define AFS_PARAM_H + +#include + +#define AFS_XBSD_ENV 1 /* {Free,Open,Net}BSD */ +#define AFS_X86_XBSD_ENV 1 + +#define AFS_NAMEI_ENV 1 /* User space interface to file system */ +#define AFS_64BIT_IOPS_ENV 1 /* Needed for NAMEI */ +#define AFS_NBSD_ENV 1 +#define AFS_NBSD15_ENV 1 +#define AFS_X86_ENV 1 +#define AFS_NONFSTRANS 1 +#define AFS_KERBEROS_ENV 1 +#define FTRUNC O_TRUNC + +#define IUPD 0x0010 +#define IACC 0x0020 +#define ICHG 0x0040 +#define IMOD 0x0080 + +#define IN_LOCK(ip) lockmgr(&ip->i_lock, LK_EXCLUSIVE, \ + (struct simplelock *)0, curproc) +#define IN_UNLOCK(ip) lockmgr(&ip->i_lock, LK_RELEASE, \ + (struct simplelock *)0, curproc) + +#include + +#define AFS_VM_RDWR_ENV 1 +#define AFS_VFS_ENV 1 +#define AFS_VFSINCL_ENV 1 +#define AFS_GREEDY43_ENV 1 +#define AFS_ENV 1 + +#define AFS_SYSCALL 210 +#define AFS_MOUNT_AFS "afs" + +#ifndef MOUNT_UFS +#define MOUNT_UFS "ufs" +#endif + +#ifndef MOUNT_AFS +#define MOUNT_AFS AFS_MOUNT_AFS +#endif +#define SYS_NAME "i386_fbsd_42" +#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_42 + +#define AFS_HAVE_FFS 1 /* Use system's ffs. */ +#define AFS_HAVE_STATVFS 0 /* System doesn't supports statvfs */ + +#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ +#define AFS_USE_GETTIMEOFDAY 1 /* use gettimeofday to implement rx clock */ + +#define AFSLITTLE_ENDIAN 1 + +/* Extra kernel definitions (from kdefs file) */ +#ifdef _KERNEL +#define AFS_GLOBAL_SUNLOCK 1 +#define AFS_VFS34 1 /* What is VFS34??? */ +#define AFS_SHORTGID 1 /* are group id's short? */ +#define afsio_iov uio_iov +#define afsio_iovcnt uio_iovcnt +#define afsio_offset uio_offset +#define afsio_seg uio_segflg +#define afsio_resid uio_resid +#define AFS_UIOSYS UIO_SYSSPACE +#define AFS_UIOUSER UIO_USERSPACE +#define AFS_CLBYTES CLBYTES +#define osi_GetTime(x) microtime(x) +#define AFS_KALLOC(x) kalloc(x) +#define AFS_KFREE(x,y) kfree(x,y) +#define v_count v_usecount +#define v_vfsp v_mount +#define vfs_bsize mnt_stat.f_bsize +#define vfs_fsid mnt_stat.f_fsid +#define va_nodeid va_fileid +#define vfs_vnodecovered mnt_vnodecovered +#define direct dirent +#define vnode_t struct vnode + +#ifndef MUTEX_DEFAULT +#define MUTEX_DEFAULT 0 +#endif /* MUTEX_DEFAULT */ + +#ifndef SSYS +#define SSYS 0x00002 +#endif /* SSYS */ + +#define p_rcred p_ucred + +#define VN_RELE(vp) vrele(((struct vnode *)(vp))) +#define VN_HOLD(vp) VREF(((struct vnode *)(vp))) + +#if !defined(ASSEMBLER) && !defined(__LANGUAGE_ASSEMBLY__) +enum vcexcl {NONEXCL, EXCL}; + +#ifdef KERNEL +#ifndef MIN +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#endif +#ifndef MAX +#define MAX(A,B) ((A) > (B) ? (A) : (B)) +#endif +#endif /* KERNEL */ + +#endif /* ! ASSEMBLER & ! __LANGUAGE_ASSEMBLY__ */ +#endif /* _KERNEL */ + +#endif /* AFS_PARAM_H */ diff --git a/src/config/param.i386_nbsd15_usr.h b/src/config/param.i386_nbsd15_usr.h new file mode 100644 index 000000000..0de935c9c --- /dev/null +++ b/src/config/param.i386_nbsd15_usr.h @@ -0,0 +1,58 @@ +#ifndef AFS_PARAM_H +#define AFS_PARAM_H + + +#define UKERNEL 1 /* user space kernel */ +#define AFS_ENV 1 +#define AFS_VFSINCL_ENV 1 +#define AFS_USR_FBSD40_ENV 1 +#define AFS_USR_FBSD42_ENV 1 +#define AFS_USR_FBSD_ENV 1 +#define AFS_NONFSTRANS 1 +#define AFS_KERBEROS_ENV + +#define AFS_MOUNT_AFS "afs" /* The name of the filesystem type. */ +#define AFS_SYSCALL 210 +#define AFS_NAMEI_ENV 1 /* User space interface to file system */ +#define AFS_64BIT_IOPS_ENV 1 /* Needed for NAMEI */ +#include + +#define AFS_USERSPACE_IP_ADDR 1 +#define RXK_LISTENER_ENV 1 +#define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ + +/* Machine / Operating system information */ +#define SYS_NAME "i386_fbsd_42" +#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_42 +#define AFSLITTLE_ENDIAN 1 +#define AFS_HAVE_FFS 1 /* Use system's ffs. */ +#define AFS_HAVE_STATVFS 0 /* System doesn't support statvfs */ +#define AFS_VM_RDWR_ENV 1 /* read/write implemented via VM */ + +#define afsio_iov uio_iov +#define afsio_iovcnt uio_iovcnt +#define afsio_offset uio_offset +#define afsio_seg uio_segflg +#define afsio_fmode uio_fmode +#define afsio_resid uio_resid +#define AFS_UIOSYS 1 +#define AFS_UIOUSER UIO_USERSPACE +#define AFS_CLBYTES MCLBYTES +#define AFS_MINCHANGE 2 +#define VATTR_NULL usr_vattr_null + +#define AFS_DIRENT +#ifndef CMSERVERPREF +#define CMSERVERPREF +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* AFS_PARAM_H */ diff --git a/src/gtx/curseswindows.c b/src/gtx/curseswindows.c index 8bfd871c3..1da3b3cb3 100644 --- a/src/gtx/curseswindows.c +++ b/src/gtx/curseswindows.c @@ -761,6 +761,9 @@ int gator_cursesgwin_getdimensions(gwp, aparms) #ifdef AFS_DARWIN_ENV aparms->maxx = cwp->wp->maxx; aparms->maxy = cwp->wp->maxy; +#elif defined(AFS_NBSD_ENV) + aparms->maxx = getmaxx(cwp->wp); + aparms->maxy = getmaxy(cwp->wp); #else aparms->maxx = cwp->wp->_maxx; aparms->maxy = cwp->wp->_maxy; diff --git a/src/libafs/MakefileProto.NBSD.in b/src/libafs/MakefileProto.NBSD.in new file mode 100644 index 000000000..88e1695b7 --- /dev/null +++ b/src/libafs/MakefileProto.NBSD.in @@ -0,0 +1,130 @@ +#/* Copyright (C) 1995, 1989 Transarc Corporation - All rights reserved */ +# +srcdir=@srcdir@ +include @TOP_OBJDIR@/src/config/Makefile.config + + +# OS specific object files: +AFS_OS_OBJS = \ + osi_groups.o \ + osi_file.o \ + osi_inode.o \ + osi_misc.o \ + osi_sleep.o \ + osi_vm.o \ + osi_vnodeops.o \ + xdr_int64.o + +AFS_OS_NFSOBJS = \ + osi_vfsops_nfs.o + +AFS_OS_NONFSOBJS = \ + osi_vfsops.o + + +# System specific build commands and flags +KDEFS=-Wall -fformat-extensions -ansi -nostdinc -I/usr/include -D_KERNEL \ + -elf -mpreferred-stack-boundary=2 -I/usr/src/sys/sys -I../afs +DBUG = -O2 +DEFINES= -DAFSDEBUG -DKERNEL -DAFS -DVICE -DNFS -DUFS -DINET -DQUOTA -DGETMOUNT +OPTF=${OPT} +OPTF2=${OPT2} +CFLAGS=-I. -I.. -I${TOP_OBJDIR}/src/config ${FSINCLUDES} $(DEFINES) $(KDEFS) $(KOPTS) ${DBUG} + + +# Name of directory to hold object files and libraries. +KOBJ = STATIC + +# This tells Makefile.common to use it's single directory build target. +COMPDIRS = single_compdir +INSTDIRS = single_instdir +DESTDIRS = single_destdir + +include Makefile.common + +setup: + -mkdir $(KOBJ) + -$(RM) $(KOBJ)/Makefile $(KOBJ)/Makefile.common $(KOBJ)/config + ln -fs ../Makefile $(KOBJ)/Makefile + ln -fs ../Makefile.common $(KOBJ)/Makefile.common + ln -fs ../config $(KOBJ)/config + -$(RM) -f h net netinet rpc ufs nfs machine sys vm + -ln -fs /usr/src/sys/net net + -ln -fs /usr/src/sys/i386/include machine + -ln -fs /usr/src/sys/netinet netinet + -ln -fs /usr/src/sys/nfs nfs + -ln -fs /usr/include/rpc rpc + -ln -fs /usr/src/sys/sys sys + -ln -fs /usr/src/sys/ufs/ufs ufs + -ln -fs /usr/src/sys/sys h + -ln -fs /usr/src/sys/vm vm + -touch $(KOBJ)/sec_net.h + + +# Below this line are targets when in the COMMON directory: +LIBAFS = libafs.o +LIBAFSNONFS = libafs.nonfs.o + +INST_LIBAFS = ${DESTDIR}${afskerneldir}/${LIBAFS} +INST_LIBAFSNONFS = ${DESTDIR}${afskerneldir}/${LIBAFSNONFS} + +DEST_LIBAFS = ${DEST}/root.client/bin/${LIBAFS} +DEST_LIBAFSNONFS = ${DEST}/root.client/bin/${LIBAFSNONFS} + + +# libafs: $(LIBAFS) $(LIBAFSNONFS) +# libafs: $(LIBAFSNONFS) +# install_libafs: $(INST_LIBAFS) $(INST_LIBAFSNONFS) +# install_libafs: $(INST_LIBAFSNONFS) +# dest_libafs: $(DEST_LIBAFS) $(DEST_LIBAFSNONFS) +# dest_libafs: $(DEST_LIBAFSNONFS) +libafs: + echo WARNING: No kernel module for ${SYS_NAME} + +install_libafs: + echo WARNING: No kernel module for ${SYS_NAME} + +dest_libafs: + echo WARNING: No kernel module for ${SYS_NAME} + + +$(INST_LIBAFS): $(LIBAFS) + $(INSTALL) -f $? $@ + +$(INST_LIBAFSNONFS): $(LIBAFSNONFS) + $(INSTALL) -f $? $@ + +$(DEST_LIBAFS): $(LIBAFS) + $(INSTALL) -f $? $@ + +$(DEST_LIBAFSNONFS): $(LIBAFSNONFS) + $(INSTALL) -f $? $@ + +${LIBAFS}: $(AFSAOBJS) $(AFSNFSOBJS) + $(LD) -r -o ${LIBAFS} ${AFSAOBJS} ${AFSNFSOBJS} + +${LIBAFSNONFS}: $(AFSAOBJS) $(AFSNONFSOBJS) + $(LD) -r -o ${LIBAFSNONFS} ${AFSAOBJS} ${AFSNONFSOBJS} + + +# Object build rules: +osi_groups.o: $(AFS)/osi_groups.c + $(CRULE1) +osi_file.o: $(AFS)/osi_file.c + $(CRULE1) +osi_inode.o: $(AFS)/osi_inode.c + $(CRULE1) +osi_misc.o: $(AFS)/osi_misc.c + $(CRULE1) +osi_sleep.o: $(AFS)/osi_sleep.c + $(CRULE1) +osi_vfsops_nfs.o: $(AFS)/osi_vfsops.c + $(CRULE1) -o osi_vfsops_nfs.o +osi_vfsops.o: $(AFS)/osi_vfsops.c + $(CRULE1) -DAFS_NONFSTRANS +osi_vm.o: $(AFS)/osi_vm.c + $(CRULE1) +osi_vnodeops.o: $(AFS)/osi_vnodeops.c + $(CRULE1) +xdr_int64.o: $(RX)/xdr_int64.c + $(CRULE1) diff --git a/src/libuafs/MakefileProto.NBSD.in b/src/libuafs/MakefileProto.NBSD.in new file mode 100644 index 000000000..a71d104cd --- /dev/null +++ b/src/libuafs/MakefileProto.NBSD.in @@ -0,0 +1,76 @@ +#/* Copyright (C) 1995, 1989 Transarc Corporation - All rights reserved */ +# +srcdir=@srcdir@ +include @TOP_OBJDIR@/src/config/Makefile.config + + +# System specific build commands and flags +CC = gcc +DEFINES= -DKERNEL -DUKERNEL +KOPTS= +CFLAGS=-I. -I.. -I${TOP_OBJDIR}/src/config ${FSINCLUDES} $(DEFINES) $(KOPTS) ${DBUG} +OPTF=-O + +TEST_CFLAGS= -DAFS_NBSD_ENV +TEST_LDFLAGS= +TEST_LIBS= + +LIBUAFS = libuafs.a +LIBAFSWEB = nsafs.so +LIBAFSWEBKRB = nsafs.krb.so + +include Makefile.common + +setup_common: + -$(RM) -f h net netinet rpc ufs nfs machine sys inet nsapi + -ln -s /usr/include/sys h + -ln -s /usr/include/net net + -ln -s /usr/include/netinet netinet + -ln -s /usr/include/rpc rpc + -ln -s /usr/include/sys sys + -ln -s /usr/include/nfs nfs + -ln -s /usr/include/inet inet + -ln -s /usr/include/ufs ufs + -ln -s $(NS_INCL) nsapi + +setup_uafs: UAFS setup_common + -$(RM) -f UAFS/Makefile UAFS/Makefile.common + ln -s ../Makefile UAFS/Makefile + ln -s ../Makefile.common UAFS/Makefile.common + +UAFS: + mkdir -p $@ + +setup_nsafs: AFSWEB setup_common + -$(RM) -f AFSWEB/Makefile AFSWEB/Makefile.common + ln -s ../Makefile AFSWEB/Makefile + ln -s ../Makefile.common AFSWEB/Makefile.common + +AFSWEB: + mkdir -p $@ + +UAFS/$(LIBUAFS): setup_uafs + cd UAFS; \ + $(MAKE) $(LIBUAFS) DESTDIR=${DESTDIR} + +AFSWEB/$(LIBAFSWEB): setup_nsafs +cd AFSWEB; \ + $(MAKE) $(LIBAFSWEB) DESTDIR=${DESTDIR} + +AFSWEB/$(LIBAFSWEBKRB): setup_nsafs + cd AFSWEB; \ + $(MAKE) $(LIBAFSWEBKRB) DESTDIR=${DESTDIR} + +# Below this line are targets when in the COMMON directory: + +$(LIBUAFS): $(UAFSOBJ) + -$(RM) -f $(LIBUAFS) + $(AR) $(ARFLAGS) $(LIBUAFS) $(UAFSOBJ) + +$(LIBAFSWEB): $(AFSWEBOBJ) ${DES}/libdes.a + -$(RM) -f $(LIBAFSWEB) + ld -b $(LIBAFSWEB) $(AFSWEBOBJ) ${DES}/libdes.a $(WEBLIBS) + +$(LIBAFSWEBKRB): $(AFSWEBOBJKRB) ${DES}/libdes.a + -$(RM) -f $(LIBAFSWEBKRB) + ld -b $(LIBAFSWEBKRB) $(AFSWEBOBJKRB) ${DES}/libdes.a $(WEBLIBS) diff --git a/src/lwp/Makefile.in b/src/lwp/Makefile.in index 6bb394d57..89eb1c6d2 100644 --- a/src/lwp/Makefile.in +++ b/src/lwp/Makefile.in @@ -50,7 +50,7 @@ process.o : process.s process.c $(RM) process.ss ;; \ ppc_darwin* ) \ $(CC) -c ${XCFLAGS} -I${TOP_INCDIR} ${srcdir}/process.s;; \ - i386_fbsd* ) \ + i386_fbsd*|i386_nbsd* ) \ /usr/bin/cpp -P ${srcdir}/process.fbsd.s > process.ss; \ ${AS} -o process.o process.ss; \ $(RM) process.ss ;; \ diff --git a/src/pinstall/install.c b/src/pinstall/install.c index f2c0b0fea..dbd26a26a 100644 --- a/src/pinstall/install.c +++ b/src/pinstall/install.c @@ -87,7 +87,7 @@ struct stat istat, ostat; extern int errno; extern int sys_nerr; -#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_FBSD_ENV) +#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV) extern char *sys_errlist[]; #endif #if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_DECOSF_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) @@ -153,7 +153,7 @@ atoo(astr) return value; } -#if defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_DECOSF_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_OBSD_ENV) +#if defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_DECOSF_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_OBSD_ENV) || defined(AFS_NBSD_ENV) /* * Implementation lifted from that for AIX 3.1, since there didn't seem to be any * reason why it wouldn't work. @@ -205,7 +205,7 @@ char *iname, *oname; { return -1; } -#ifndef AFS_OBSD_ENV +#if !defined(AFS_OBSD_ENV) && !defined(AFS_NBSD_ENV) /* * done the copy, now strip if desired. */ @@ -687,7 +687,7 @@ main (argc, argv) continue; } } -#if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_DECOSF_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_OBSD_ENV) +#if defined(AFS_AIX_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_DECOSF_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_OBSD_ENV) || defined(AFS_NBSD_ENV) stripcalled = 0; if (strip == 1 || ((strip == -1 && ((istat.st_mode & 0111) == 0111) && stripName(newNames[i])) && AIXobject(fnames[i]))) diff --git a/src/rx/NBSD/rx_kmutex.h b/src/rx/NBSD/rx_kmutex.h new file mode 100644 index 000000000..530b3ceba --- /dev/null +++ b/src/rx/NBSD/rx_kmutex.h @@ -0,0 +1,107 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +/* + * rx_kmutex.h - mutex and condition variable macros for kernel environment. + * + * MACOS implementation. + */ + +#ifndef _RX_KMUTEX_H_ +#define _RX_KMUTEX_H_ + +#include +#include +#include + +#define RX_ENABLE_LOCKS 1 +#define AFS_GLOBAL_RXLOCK_KERNEL + +/* + * Condition variables + * + * In Digital Unix (OSF/1), we use something akin to the ancient sleep/wakeup + * mechanism. The condition variable itself plays no role; we just use its + * address as a convenient unique number. + * + * XXX in darwin, both mach and bsd facilities are available. Should really + * stick to one or the other (but mach locks don't have a _try.....) + */ +#define CV_INIT(cv,a,b,c) +#define CV_DESTROY(cv) +#define CV_WAIT(cv, lck) { \ + int isGlockOwner = ISAFS_GLOCK(); \ + if (isGlockOwner) AFS_GUNLOCK(); \ + assert_wait((event_t)(cv), 0); \ + MUTEX_EXIT(lck); \ + thread_block(0); \ + if (isGlockOwner) AFS_GLOCK(); \ + MUTEX_ENTER(lck); \ + } + +#define CV_TIMEDWAIT(cv,lck,t) { \ + int isGlockOwner = ISAFS_GLOCK(); \ + if (isGlockOwner) AFS_GUNLOCK(); \ + assert_wait((event_t)(cv), 0); \ + thread_set_timer(t, NSEC_PER_SEC/hz); \ + MUTEX_EXIT(lck); \ + thread_block(0); \ + if (isGlockOwner) AFS_GLOCK(); \ + MUTEX_ENTER(lck); \ + +#define CV_SIGNAL(cv) thread_wakeup_one((event_t)(cv)) +#define CV_BROADCAST(cv) thread_wakeup((event_t)(cv)) + +typedef struct { + struct lock__bsd__ lock; + thread_t owner; +} afs_kmutex_t; +typedef int afs_kcondvar_t; + +#define osi_rxWakeup(cv) thread_wakeup((event_t)(cv)) + +#define LOCK_INIT(a,b) \ + do { \ + lockinit(&(a)->lock,PSOCK, "afs rx lock", 0, 0); \ + (a)->owner = (thread_t)0; \ + } while(0); +#define MUTEX_INIT(a,b,c,d) \ + do { \ + lockinit(&(a)->lock,PSOCK, "afs rx mutex", 0, 0); \ + (a)->owner = (thread_t)0; \ + } while(0); +#define MUTEX_DESTROY(a) \ + do { \ + (a)->owner = (thread_t)-1; \ + } while(0); +#define MUTEX_ENTER(a) \ + do { \ + lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, current_proc()); \ + osi_Assert((a)->owner == (thread_t)0); \ + (a)->owner = current_thread(); \ + } while(0); +#define MUTEX_TRYENTER(a) \ + ( lockmgr(&(a)->lock, LK_EXCLUSIVE|LK_NOWAIT, 0, current_proc()) ? 0 : ((a)->owner = current_thread(), 1) ) +#define xMUTEX_TRYENTER(a) \ + ( osi_Assert((a)->owner == (thread_t)0), (a)->owner = current_thread(), 1) +#define MUTEX_EXIT(a) \ + do { \ + osi_Assert((a)->owner == current_thread()); \ + (a)->owner = (thread_t)0; \ + lockmgr(&(a)->lock, LK_RELEASE, 0, current_proc()); \ + } while(0); + +#undef MUTEX_ISMINE +#define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == current_thread()) + +#undef osirx_AssertMine +extern void osirx_AssertMine(afs_kmutex_t *lockaddr, char *msg); + +#endif /* _RX_KMUTEX_H_ */ + diff --git a/src/rx/NBSD/rx_knet.c b/src/rx/NBSD/rx_knet.c new file mode 100644 index 000000000..f069eed1c --- /dev/null +++ b/src/rx/NBSD/rx_knet.c @@ -0,0 +1,167 @@ +/* + * Copyright 2000, International Business Machines Corporation and others. + * All Rights Reserved. + * + * This software has been released under the terms of the IBM Public + * License. For details, see the LICENSE file in the top-level source + * directory or online at http://www.openafs.org/dl/license10.html + */ + +#include +#include "../afs/param.h" + +RCSID("$Header$"); + +#include "../rx/rx_kcommon.h" + +int osi_NetReceive(asocket, addr, dvec, nvecs, alength) + struct socket *asocket; + struct sockaddr_in *addr; + struct iovec *dvec; + int nvecs; + int *alength; +{ + struct uio u; + int i; + struct iovec iov[RX_MAXIOVECS]; + struct sockaddr *sa; + int code; + + int haveGlock = ISAFS_GLOCK(); + /*AFS_STATCNT(osi_NetReceive);*/ + + if (nvecs > RX_MAXIOVECS) { + osi_Panic("osi_NetReceive: %d: Too many iovecs.\n", nvecs); + } + + for (i = 0 ; i < nvecs ; i++) { + iov[i].iov_base = dvec[i].iov_base; + iov[i].iov_len = dvec[i].iov_len; + } + + u.uio_iov=&iov[0]; + u.uio_iovcnt=nvecs; + u.uio_offset=0; + u.uio_resid=*alength; + u.uio_segflg=UIO_SYSSPACE; + u.uio_rw=UIO_READ; + u.uio_procp=NULL; + + if (haveGlock) { + AFS_GUNLOCK(); + } +#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) + thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); +#endif + code = soreceive(asocket, &sa, &u, NULL, NULL, NULL); +#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) + thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); +#endif + if (haveGlock) { + AFS_GLOCK(); + } + *alength=*alength-u.uio_resid; + if (sa) { + if (sa->sa_family == AF_INET) { + if (addr) *addr=*(struct sockaddr_in *)sa; + } else { + printf("Unknown socket family %d in NetReceive\n"); + } + } + return code; +} + +extern int rxk_ListenerPid; +void osi_StopListener(void) +{ + struct proc *p; + +#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) + thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); +#endif + soclose(rx_socket); +#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) + thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); +#endif + p=pfind(rxk_ListenerPid); + if (p) + psignal(p, SIGUSR1); +} + +/* rx_NetSend - send asize bytes at adata from asocket to host at addr. + * + * Now, why do we allocate a new buffer when we could theoretically use the one + * pointed to by adata? Because PRU_SEND returns after queueing the message, + * not after sending it. If the sender changes the data after queueing it, + * we'd see the already-queued data change. One attempt to fix this without + * adding a copy would be to have this function wait until the datagram is + * sent; however this doesn't work well. In particular, if a host is down, and + * an ARP fails to that host, this packet will be queued until the ARP request + * comes back, which could be hours later. We can't block in this routine that + * long, since it prevents RPC timeouts from happening. + */ +/* XXX In the brave new world, steal the data bufs out of the rx_packet iovec, + * and just queue those. XXX + */ + + +int +osi_NetSend(asocket, addr, dvec, nvecs, alength, istack) + register struct socket *asocket; + struct iovec *dvec; + int nvecs; + register afs_int32 alength; + struct sockaddr_in *addr; + int istack; +{ + register afs_int32 code; + int s; + int len; + int i; + struct iovec iov[RX_MAXIOVECS]; + char *tdata; + struct uio u; + struct mbuf *nam; + int haveGlock = ISAFS_GLOCK(); + + AFS_STATCNT(osi_NetSend); + if (nvecs > RX_MAXIOVECS) { + osi_Panic("osi_NetSend: %d: Too many iovecs.\n", nvecs); + } + + for (i = 0 ; i < nvecs ; i++) { + iov[i].iov_base = dvec[i].iov_base; + iov[i].iov_len = dvec[i].iov_len; + } + + u.uio_iov=&iov[0]; + u.uio_iovcnt=nvecs; + u.uio_offset=0; + u.uio_resid=alength; + u.uio_segflg=UIO_SYSSPACE; + u.uio_rw=UIO_WRITE; + u.uio_procp=NULL; + if (haveGlock) { + AFS_GUNLOCK(); + } +#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) + thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL); +#endif + nam=m_get(M_DONTWAIT, MT_SONAME); + if (nam == NULL) { + code=ENOBUFS; + goto bad; + } + nam->m_len=addr->sin_len=sizeof(struct sockaddr_in); + memcpy(mtod(nam, caddr_t), (caddr_t)addr, addr->sin_len); + code = sosend(asocket, mtod(nam, struct sockaddr *), &u, NULL, NULL, 0); + m_freem(nam); +bad: +#if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL) + thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL); +#endif + if (haveGlock) { + AFS_GLOCK(); + } + return code; +} diff --git a/src/usd/usd_file.c b/src/usd/usd_file.c index c103dd94a..e3f571896 100644 --- a/src/usd/usd_file.c +++ b/src/usd/usd_file.c @@ -26,7 +26,7 @@ RCSID("$Header$"); #endif #include #endif /* AFS_AIX_ENV */ -#if defined(AFS_DUX40_ENV) || defined(AFS_OBSD_ENV) +#if defined(AFS_DUX40_ENV) || defined(AFS_OBSD_ENV) || defined(AFS_NBSD_ENV) #include #endif #include diff --git a/src/uss/uss_common.h b/src/uss/uss_common.h index aeb8201ea..782fc1bfc 100644 --- a/src/uss/uss_common.h +++ b/src/uss/uss_common.h @@ -59,7 +59,7 @@ #define uss_VolumeLen 300 #define uss_DirPoolLen 300 -#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_FBSD_ENV) +#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV) extern char *sys_errlist[]; #endif diff --git a/src/venus/up.c b/src/venus/up.c index 51d158c5b..8db512a22 100644 --- a/src/venus/up.c +++ b/src/venus/up.c @@ -49,7 +49,7 @@ RCSID("$Header$"); #define MAXACL 400 -#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_FBSD_ENV) +#if !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV) extern sys_nerr; extern char *sys_errlist[]; #endif -- 2.39.5