From: Chaskiel M Grundman Date: Sat, 16 Feb 2002 18:23:44 +0000 (+0000) Subject: freebsd-almost-working-client-20020216 X-Git-Tag: openafs-devel-1_3_0 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=bd707fb7e6e037ba0ae6e9addedca907cdaf5af0 freebsd-almost-working-client-20020216 a) a freebsd client that compiles, and to a certain extent, works. Should not be used except by people doing freebsd client development b) configure glue for freebsd 4.3, 4.4, and 4.5 c) freebsd tfileserver support. Note that, by default, this isn't very interesting, as the supported freebsd pthreads are just as cooperative as LWP. if you install the linuxthreads port and swap the MT_* variables in osconf.m4, you will get a more traditional tfileserver though. configure glue for that will be forthcoming at some point. d) a maybe-fix that sets sin_len in sockaddrs on platforms that have them. (and also a fix for the AC_PROG_CC issue which affects autoconf 2.13 and 2.5x on same conf files issue) --- diff --git a/Makefile.in b/Makefile.in index f8f5842..e4c907d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -206,7 +206,7 @@ viced: project vlserver audit tviced: project viced vlserver libafsrpc libafsauthent case ${SYS_NAME} in \ - alpha_dux*|sgi_*|sun4x_*|sunx86_*|rs_aix*|*linux*|hp_ux110) \ + alpha_dux*|sgi_*|sun4x_*|sunx86_*|rs_aix*|*linux*|hp_ux110|*fbsd*) \ ${COMPILE_PART1} tviced ${COMPILE_PART2} ;; \ *) \ echo Not building MT viced for ${SYS_NAME} ;; \ @@ -400,7 +400,7 @@ tests: rxtests ubiktests # pthread based user space RX library libafsrpc: rx rxkad des case ${SYS_NAME} in \ - alpha_dux*|sgi_*|sun4x_*|sunx86_*|rs_aix*|*linux*|hp_ux110) \ + alpha_dux*|sgi_*|sun4x_*|sunx86_*|rs_aix*|*linux*|hp_ux110|*fbsd*) \ ${COMPILE_PART1} libafsrpc ${COMPILE_PART2} ;; \ *) \ echo Not building MT libafsrpc for ${SYS_NAME} ;; \ @@ -408,7 +408,7 @@ libafsrpc: rx rxkad des libafsauthent: ubik auth kauth libafsrpc case ${SYS_NAME} in \ - alpha_dux*|sgi_*|sun4x_*|sunx86_*|rs_aix*|*linux*|hp_ux110) \ + alpha_dux*|sgi_*|sun4x_*|sunx86_*|rs_aix*|*linux*|hp_ux110|*fbsd*) \ ${COMPILE_PART1} libafsauthent ${COMPILE_PART2} ;; \ *) \ echo Not building MT libafsrpc for ${SYS_NAME} ;; \ diff --git a/acconfig.h b/acconfig.h index f2d0879..fa26c8e 100644 --- a/acconfig.h +++ b/acconfig.h @@ -9,6 +9,7 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg } #undef HAVE_GETHOSTBYNAME #undef HAVE_RES_SEARCH #undef HAVE_SOCKET +#undef STRUCT_SOCKADDR_HAS_SA_LEN #if ENDIANESS_IN_SYS_PARAM_H # ifndef KERNEL diff --git a/acinclude.m4 b/acinclude.m4 index cb30b9c..95f6a53 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -54,9 +54,6 @@ AC_ISC_POSIX AC_MINIX dnl Various compiler setup. -AC_C_INLINE -AC_C_CONST -AC_PROG_CC AC_TYPE_PID_T AC_TYPE_SIZE_T AC_TYPE_SIGNAL @@ -214,6 +211,15 @@ else i?86-*-freebsd4.2*) AFS_SYSNAME="i386_fbsd_42" ;; + i?86-*-freebsd4.3*) + AFS_SYSNAME="i386_fbsd_43" + ;; + i?86-*-freebsd4.4*) + AFS_SYSNAME="i386_fbsd_44" + ;; + i?86-*-freebsd4.5*) + AFS_SYSNAME="i386_fbsd_45" + ;; i?86-*-netbsd*1.5*) AFS_PARAM_COMMON=param.nbsd15.h AFS_SYSNAME="i386_nbsd15" @@ -321,7 +327,17 @@ case $AFS_SYSNAME in DARWIN_INFOFILE=afs.${AFS_SYSNAME}.plist ;; esac - +AC_CACHE_VAL(ac_cv_sockaddr_len, +[ +AC_MSG_CHECKING([if struct sockaddr has sa_len field]) +AC_TRY_COMPILE( [#include +#include ], +[struct sockaddr *a; +a->sa_len=0;], ac_cv_sockaddr_len=yes, ac_cv_sockaddr_len=no) +AC_MSG_RESULT($ac_cv_sockaddr_len)]) +if test "$ac_cv_sockaddr_len" = "yes"; then + AC_DEFINE(STRUCT_SOCKADDR_HAS_SA_LEN) +fi if test "x${MKAFS_OSTYPE}" = "xIRIX"; then echo Skipping library tests because they confuse Irix. else diff --git a/configure-libafs.in b/configure-libafs.in index b8cf1ac..0b740e6 100644 --- a/configure-libafs.in +++ b/configure-libafs.in @@ -3,6 +3,7 @@ AM_INIT_AUTOMAKE(openafs-libafs,devel) AC_CONFIG_HEADER(config/afsconfig.h) define(OPENAFS_CONFIGURE_LIBAFS) +AC_PROG_CC OPENAFS_CONFIGURE_COMMON TOP_SRCDIR="${SRCDIR_PARENT}" diff --git a/configure.in b/configure.in index ef7526f..6df54c1 100644 --- a/configure.in +++ b/configure.in @@ -2,6 +2,7 @@ AC_INIT(src/config/stds.h) AM_INIT_AUTOMAKE(openafs,devel) AC_CONFIG_HEADER(src/config/afsconfig.h) +AC_PROG_CC OPENAFS_CONFIGURE_COMMON TOP_SRCDIR="${srcdir}/src" diff --git a/src/afs/FBSD/osi_file.c b/src/afs/FBSD/osi_file.c index 26e4b7c..f22cd54 100644 --- a/src/afs/FBSD/osi_file.c +++ b/src/afs/FBSD/osi_file.c @@ -50,8 +50,8 @@ void *osi_UFSOpen(ainode) osi_FreeSmallSpace(afile); osi_Panic("UFSOpen: igetinode failed"); } - IN_UNLOCK(ip); afile->vnode = ITOV(ip); + VOP_UNLOCK(afile->vnode, 0, curproc); afile->size = VTOI(afile->vnode)->i_size; afile->offset = 0; afile->proc = (int (*)()) 0; @@ -67,7 +67,7 @@ afs_osi_Stat(afile, astat) AFS_STATCNT(osi_Stat); MObtainWriteLock(&afs_xosi,320); AFS_GUNLOCK(); - VOP_GETATTR(afile->vnode, &tvattr, &afs_osi_cred, code); + code=VOP_GETATTR(afile->vnode, &tvattr, &afs_osi_cred, curproc); AFS_GLOCK(); if (code == 0) { astat->size = tvattr.va_size; @@ -94,7 +94,6 @@ osi_UFSClose(afile) 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; @@ -108,17 +107,10 @@ osi_UFSTruncate(afile, asize) 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); + code=VOP_SETATTR(afile->vnode, &tvattr, &afs_osi_cred, curproc); AFS_GLOCK(); - curproc->p_cred->pc_ucred = oldCred; /* restore */ MReleaseWriteLock(&afs_xosi); return code; } @@ -127,7 +119,7 @@ void osi_DisableAtimes(avp) struct vnode *avp; { struct inode *ip = VTOI(avp); - ip->i_flag &= ~IACC; + ip->i_flag &= ~IN_ACCESS; } @@ -137,7 +129,6 @@ afs_osi_Read(afile, offset, aptr, asize) int offset; char *aptr; afs_int32 asize; { - struct AFS_UCRED *oldCred; unsigned int resid; register afs_int32 code; register afs_int32 cnt1=0; @@ -178,7 +169,6 @@ afs_osi_Write(afile, offset, aptr, asize) char *aptr; afs_int32 offset; afs_int32 asize; { - struct AFS_UCRED *oldCred; unsigned int resid; register afs_int32 code; AFS_STATCNT(osi_Write); @@ -186,13 +176,10 @@ afs_osi_Write(afile, offset, aptr, asize) 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; diff --git a/src/afs/FBSD/osi_groups.c b/src/afs/FBSD/osi_groups.c index 77f4d64..e55c535 100644 --- a/src/afs/FBSD/osi_groups.c +++ b/src/afs/FBSD/osi_groups.c @@ -6,7 +6,6 @@ * 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 * @@ -24,11 +23,6 @@ RCSID("$Header$"); #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, @@ -51,27 +45,33 @@ Afs_xsetgroups(p, args, retval) { int code = 0; struct vrequest treq; + struct ucred *cr; + + cr=crdup(p->p_cred->pc_ucred); AFS_STATCNT(afs_xsetgroups); AFS_GLOCK(); - - /* code = afs_InitReq(&treq, u.u_cred); */ - code = afs_InitReq(&treq, curproc->p_cred->pc_ucred); + + code = afs_InitReq(&treq, cr); AFS_GUNLOCK(); - if (code) return code; + crfree(cr); + if (code) return setgroups(p, args, retval); /* afs has shut down */ 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) { + cr=crdup(p->p_cred->pc_ucred); + + if (PagInCred(cr) == 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); + AddPag(p, treq.uid, &cr ); AFS_GUNLOCK(); } } + crfree(cr); return code; } @@ -90,18 +90,18 @@ setpag(proc, cred, pagvalue, newpag, change_parent) AFS_STATCNT(setpag); ngroups = afs_getgroups(*cred, NGROUPS, gidset); - if (afs_get_pag_from_groups(gidset[0], gidset[1]) == NOPAG) { + if (afs_get_pag_from_groups(gidset[1], gidset[2]) == 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]; - } + for (j = ngroups -1; j >= 1; j--) { + gidset[j+2] = gidset[j]; + } ngroups += 2; } *newpag = (pagvalue == -1 ? genpag(): pagvalue); - afs_get_groups_from_pag(*newpag, &gidset[0], &gidset[1]); + afs_get_groups_from_pag(*newpag, &gidset[1], &gidset[2]); code = afs_setgroups(proc, cred, ngroups, gidset, change_parent); return code; } @@ -137,7 +137,7 @@ afs_setgroups( int ngrps; int i; gid_t *gp; - struct ucred *newcr, *cr; + struct ucred *oldcr, *cr; AFS_STATCNT(afs_setgroups); /* @@ -147,18 +147,19 @@ afs_setgroups( 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; + cr->cr_ngroups = ngroups; + gp = cr->cr_groups; while (ngroups--) *gp++ = *gidset++; - if (!change_parent) { - substitute_real_creds(proc, NOUID, NOUID, NOGID, NOGID, newcr); + if (change_parent) { + crhold(cr); + oldcr=proc->p_pptr->p_cred->pc_ucred; + proc->p_pptr->p_cred->pc_ucred=cr; + crfree(oldcr); } - *cred = newcr; + crhold(cr); + oldcr=proc->p_cred->pc_ucred; + proc->p_cred->pc_ucred=cr; + crfree(oldcr); return(0); } diff --git a/src/afs/FBSD/osi_inode.c b/src/afs/FBSD/osi_inode.c index 6d8b88d..42f02d1 100644 --- a/src/afs/FBSD/osi_inode.c +++ b/src/afs/FBSD/osi_inode.c @@ -34,19 +34,16 @@ getinode(fs, dev, inode, ipp, perror) ino_t inode; int *perror; { - register struct vnode *vp; - char fake_vnode[FAKE_INODE_SIZE]; - struct inode *ip; + struct vnode *vp; int code; *ipp = 0; *perror = 0; if (!fs) { register struct ufsmount *ump; - register struct vnode *vp; register struct mount *mp; - MOUNTLIST_LOCK(); + simple_lock(&mountlist_slock); if (mp = TAILQ_FIRST(&mountlist)) do { /* * XXX Also do the test for MFS @@ -54,29 +51,25 @@ getinode(fs, dev, inode, ipp, perror) #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(); + simple_unlock(&mountlist_slock); if (!fs) return(ENXIO); } - vp = (struct vnode *) fake_vnode; - fake_inode_init(vp, fs); - code = iget(VTOI(vp), inode, &ip, 0); + code = VFS_VGET(fs,inode, &vp); if (code != 0) { *perror = BAD_IGET; return code; } else { - *ipp = ip; + *ipp = VTOI(vp); return(0); } } @@ -102,12 +95,12 @@ igetinode(vfsp, dev, inode, ipp, perror) if (ip->i_mode == 0) { /* Not an allocated inode */ - iforget(ip); + vput(ITOV(ip)); return(ENOENT); } if (ip->i_nlink == 0 || (ip->i_mode&IFMT) != IFREG) { - iput(ip); + vput(ITOV(ip)); return(ENOENT); } @@ -115,23 +108,7 @@ igetinode(vfsp, dev, inode, ipp, perror) 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); - } -} - +#if 0 /* * icreate system call -- create an inode */ @@ -281,3 +258,23 @@ afs_syscall_iincdec(dev, inode, inode_p1, amount) iput(ip); return(0); } +#else +afs_syscall_icreate(dev, near_inode, param1, param2, param3, param4, retval) + long *retval; + long dev, near_inode, param1, param2, param3, param4; +{ + return EOPNOTSUPP; +} +afs_syscall_iopen(dev, inode, usrmod, retval) + long *retval; + int dev, inode, usrmod; +{ + return EOPNOTSUPP; +} +afs_syscall_iincdec(dev, inode, inode_p1, amount) + int dev, inode, inode_p1, amount; +{ + return EOPNOTSUPP; +} +#endif + diff --git a/src/afs/FBSD/osi_machdep.h b/src/afs/FBSD/osi_machdep.h index b0c0442..b134ad6 100644 --- a/src/afs/FBSD/osi_machdep.h +++ b/src/afs/FBSD/osi_machdep.h @@ -9,7 +9,7 @@ /* * - * DUX OSI header file. Extends afs_osi.h. + * FBSD 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 @@ -20,6 +20,7 @@ #define _OSI_MACHDEP_H_ #include +#include /* #include */ /* #include */ @@ -29,8 +30,7 @@ extern struct simplelock afs_rxglobal_lock; /* * Time related macros */ -extern struct timeval time; -#define osi_Time() (time.tv_sec) +#define osi_Time() time_second #define afs_hz hz #define PAGESIZE 8192 @@ -40,52 +40,43 @@ extern struct timeval time; #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 osi_vnhold(avc,r) do { VN_HOLD((struct vnode *)(avc)); } 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 gop_lookupname +#define gop_lookupname osi_lookupname #undef afs_suser #ifdef KERNEL -extern struct simplelock afs_global_lock; -#if 0 -extern thread_t afs_global_owner; +extern struct proc * afs_global_owner; +extern struct lock afs_global_lock; #define AFS_GLOCK() \ do { \ - usimple_lock(&afs_global_lock); \ - osi_Assert(afs_global_owner == (thread_t)0); \ - afs_global_owner = current_thread(); \ + osi_Assert(curproc); \ + lockmgr(&afs_global_lock, LK_EXCLUSIVE, 0, curproc); \ + osi_Assert(afs_global_owner == 0); \ + afs_global_owner = curproc; \ } while (0) #define AFS_GUNLOCK() \ do { \ - osi_Assert(afs_global_owner == current_thread()); \ - afs_global_owner = (thread_t)0; \ - usimple_unlock(&afs_global_lock); \ + osi_Assert(curproc); \ + osi_Assert(afs_global_owner == curproc); \ + afs_global_owner = 0; \ + lockmgr(&afs_global_lock, LK_RELEASE, 0, curproc); \ } 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 ISAFS_GLOCK() (afs_global_owner == curproc && curproc) #define AFS_RXGLOCK() #define AFS_RXGUNLOCK() #define ISAFS_RXGLOCK() 1 #undef SPLVAR -#define SPLVAR +#define SPLVAR int splvar #undef NETPRI -#define NETPRI +#define NETPRI splvar=splnet() #undef USERPRI -#define USERPRI +#define USERPRI splx(splvar) #endif /* KERNEL */ #endif /* _OSI_MACHDEP_H_ */ diff --git a/src/afs/FBSD/osi_misc.c b/src/afs/FBSD/osi_misc.c index 1064a1a..8e5a8ab 100644 --- a/src/afs/FBSD/osi_misc.c +++ b/src/afs/FBSD/osi_misc.c @@ -21,7 +21,7 @@ RCSID("$Header$"); #include "../afs/sysincludes.h" /* Standard vendor system headers */ #include "../afs/afsincludes.h" /* Afs-based standard headers */ - +#include /* * afs_suser() returns true if the caller is superuser, false otherwise. * @@ -36,3 +36,29 @@ afs_suser() { } return(0); } + +int osi_lookupname(char *aname, enum uio_seg seg, int followlink, + struct vnode **dirvpp, struct vnode **vpp) +{ + struct nameidata n; + int flags,error; + flags=0; + flags=LOCKLEAF; + if (followlink) + flags|=FOLLOW; + else + flags|=NOFOLLOW; +/* if (dirvpp) flags|=WANTPARENT;*/ /* XXX LOCKPARENT? */ + NDINIT(&n, LOOKUP, flags, seg, aname, curproc); + if (error=namei(&n)) + return error; + *vpp=n.ni_vp; +/* + if (dirvpp) + *dirvpp = n.ni_dvp; +*/ + /* should we do this? */ + VOP_UNLOCK(n.ni_vp, 0, curproc); + NDFREE(&n, NDF_ONLY_PNBUF); + return 0; +} diff --git a/src/afs/FBSD/osi_module.c b/src/afs/FBSD/osi_module.c new file mode 100644 index 0000000..1b8fbd9 --- /dev/null +++ b/src/afs/FBSD/osi_module.c @@ -0,0 +1,91 @@ + + +#include +#include +#include +#include +#include +#include +#include + +extern struct vfsops afs_vfsops; +extern struct vnodeopv_desc afs_vnodeop_opv_desc; +extern struct mount *afs_globalVFS; +static struct vfsconf afs_vfsconf; + +MALLOC_DEFINE(M_AFS, "afsmisc", "memory used by the AFS filesystem"); + +extern int afs3_syscall(); +extern int Afs_xsetgroups(); +extern int afs_xioctl(); + +int afs_module_handler(module_t mod, int what, void *arg) { + static sy_call_t *old_handler; + static int inited=0; + int error; + error=0; + switch (what) { + case MOD_LOAD: + if (inited) { + printf ("afs cannot be MOD_LOAD'd more than once\n"); + error=-1; + break; + } + if (sysent[AFS_SYSCALL].sy_call != nosys && + sysent[AFS_SYSCALL].sy_call != lkmnosys) { + printf("AFS_SYSCALL in use. aborting\n"); + error=-1; + break; + } + memset(&afs_vfsconf, 0, sizeof(struct vfsconf)); + strcpy(afs_vfsconf.vfc_name, "AFS"); + afs_vfsconf.vfc_vfsops=&afs_vfsops; + afs_vfsconf.vfc_typenum=-1; /* set by vfs_register */ + afs_vfsconf.vfc_flags=VFCF_NETWORK; + vfs_register(&afs_vfsconf); /* doesn't fail */ + vfs_add_vnodeops(&afs_vnodeop_opv_desc); + osi_Init(); + sysent[SYS_setgroups].sy_call=Afs_xsetgroups; + sysent[SYS_ioctl].sy_call=afs_xioctl; + old_handler=sysent[AFS_SYSCALL].sy_call; + sysent[AFS_SYSCALL].sy_call=afs3_syscall; + sysent[AFS_SYSCALL].sy_narg = 5; + inited=1; + break; + case MOD_UNLOAD: +#ifndef RXK_LISTENER_ENV + /* shutdown is incomplete unless RXK_LISTENER_ENV */ + printf("afs: I can't be unloaded yet\n"); + return -1; +#endif + if (! inited) { + error=0; + break; + } + if (afs_globalVFS) { + error=-1; + break; + } + if (vfs_unregister(&afs_vfsconf)) { + error=-1; + break; + } + vfs_rm_vnodeops(&afs_vnodeop_opv_desc); + sysent[SYS_ioctl].sy_call = ioctl; + sysent[SYS_setgroups].sy_call = setgroups; + sysent[AFS_SYSCALL].sy_narg = 0; + sysent[AFS_SYSCALL].sy_call = old_handler; + break; + } + + return (error); +} + + +static moduledata_t afs_mod = { + "afs", + afs_module_handler, + &afs_mod +}; +DECLARE_MODULE(afs, afs_mod, SI_SUB_VFS, SI_ORDER_MIDDLE); + diff --git a/src/afs/FBSD/osi_prototypes.h b/src/afs/FBSD/osi_prototypes.h new file mode 100644 index 0000000..b6bac79 --- /dev/null +++ b/src/afs/FBSD/osi_prototypes.h @@ -0,0 +1,20 @@ +/* + * 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_prototypes.h + * + * Exported macos support routines. + */ +#ifndef _OSI_PROTO_H_ +#define _OSI_PROTO_H_ + +/* osi_misc.c */ +extern int osi_lookupname(char *aname, enum uio_seg seg, int followlink, + struct vnode **dirvpp, struct vnode **vpp); +#endif /* _OSI_PROTO_H_ */ diff --git a/src/afs/FBSD/osi_sleep.c b/src/afs/FBSD/osi_sleep.c index 1b018a5..1338eb2 100644 --- a/src/afs/FBSD/osi_sleep.c +++ b/src/afs/FBSD/osi_sleep.c @@ -134,9 +134,8 @@ void afs_osi_Sleep(char *event) seq = evp->seq; while (seq == evp->seq) { AFS_ASSERT_GLOCK(); - assert_wait((vm_offset_t)(&evp->cond), 0); AFS_GUNLOCK(); - thread_block(); + tsleep(event, PVFS, "afs_osi_Sleep", 0); AFS_GLOCK(); } relevent(evp); @@ -162,20 +161,22 @@ static int osi_TimedSleep(char *event, afs_int32 ams, int aintok) int code = 0; struct afs_event *evp; int ticks; - + int seq,prio; + ticks = ( ams * afs_hz )/1000; evp = afs_getevent(event); - - assert_wait((vm_offset_t)(&evp->cond), aintok); + seq=evp->seq; AFS_GUNLOCK(); - thread_set_timeout(ticks); - thread_block(); + if (aintok) + prio=PCATCH|PPAUSE; + else + prio=PVFS; + code=tsleep(event, prio, "afs_osi_TimedSleep", ticks); AFS_GLOCK(); - /* if (current_thread()->wait_result != THREAD_AWAKENED) - code = EINTR; */ - + if (seq == evp->seq) + code=EINTR; relevent(evp); return code; } @@ -188,7 +189,7 @@ void afs_osi_Wakeup(char *event) evp = afs_getevent(event); if (evp->refcount > 1) { evp->seq++; - thread_wakeup((vm_offset_t)(&evp->cond)); + wakeup(event); } relevent(evp); } diff --git a/src/afs/FBSD/osi_vfsops.c b/src/afs/FBSD/osi_vfsops.c index 3ab83bb..aba84ac 100644 --- a/src/afs/FBSD/osi_vfsops.c +++ b/src/afs/FBSD/osi_vfsops.c @@ -1,52 +1,69 @@ -/* - * 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" +#include 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 /* Standard vendor system headers */ +#include /* Afs-based standard headers */ +#include /* statistics */ +#include +#include #include -#include - +#include struct vcache *afs_globalVp = 0; struct mount *afs_globalVFS = 0; +int afs_pbuf_freecnt=-1; +int +afs_quotactl() +{ + return EOPNOTSUPP; +} -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 +afs_fhtovp(mp, fhp, vpp) +struct mount *mp; +struct fid *fhp; +struct vnode **vpp; +{ + return (EINVAL); +} -int mp_afs_mount(struct mount *afsp,char * path, caddr_t data, - struct nameidata *ndp) +int +afs_vptofh(vp, fhp) +struct vnode *vp; +struct fid *fhp; { - u_int size; - fsid_t tfsid; - struct mount *xmp, *getvfs(); - int code; + return (EINVAL); +} + +int +afs_start(mp, flags, p) +struct mount *mp; +int flags; +struct proc *p; +{ + afs_pbuf_freecnt = nswbuf / 2 + 1; + return (0); /* nothing to do. ? */ +} + +int +afs_mount(mp, path, data, ndp, p) +register struct mount *mp; +char *path; +caddr_t data; +struct nameidata *ndp; +struct proc *p; +{ + /* ndp contains the mounted-from device. Just ignore it. + we also don't care about our proc struct. */ + size_t size; + int error; + + if (mp->mnt_flag & MNT_UPDATE) + return EINVAL; AFS_GLOCK(); AFS_STATCNT(afs_mount); @@ -56,130 +73,111 @@ int mp_afs_mount(struct mount *afsp,char * path, caddr_t data, 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_globalVFS = mp; + mp->vfs_bsize = 8192; + vfs_getnewfsid(mp); + mp->mnt_stat.f_iosize=8192; + + (void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN-1, &size); + memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size); + memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN); + strcpy(mp->mnt_stat.f_mntfromname, "AFS"); + /* null terminated string "AFS" will fit, just leave it be. */ + strcpy(mp->mnt_stat.f_fstypename, "afs"); AFS_GUNLOCK(); + (void) afs_statfs(mp, &mp->mnt_stat, p); return 0; } - -int mp_afs_unmount (struct mount *afsp, int flag) +int +afs_unmount(mp, flags, p) +struct mount *mp; +int flags; +struct proc *p; { + 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); + return 0; } -int mp_afs_root (struct mount *afsp, struct vnode **avpp) +int +afs_root(struct mount *mp, + struct vnode **vpp) { - register afs_int32 code = 0; + int error; struct vrequest treq; register struct vcache *tvp=0; + struct proc *p=curproc; + struct ucred cr; + cr=*p->p_cred->pc_ucred; AFS_GLOCK(); AFS_STATCNT(afs_root); if (afs_globalVp && (afs_globalVp->states & CStatd)) { tvp = afs_globalVp; + error=0; } else { - if (!(code = afs_InitReq(&treq, cred)) && - !(code = afs_CheckInit())) { + + if (!(error = afs_InitReq(&treq, &cr)) && + !(error = afs_CheckInit())) { tvp = afs_GetVCache(&afs_rootFid, &treq, (afs_int32 *)0, - (struct vcache*)0, WRITE_LOCK); + (struct vcache*)0, WRITE_LOCK); /* we really want this to stay around */ if (tvp) { - afs_globalVp = tvp; + afs_globalVp = tvp; } else - code = ENOENT; + error = 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; + osi_vnhold(tvp,0); + AFS_GUNLOCK(); + vn_lock((struct vnode *)tvp, LK_EXCLUSIVE | LK_RETRY, p); + AFS_GLOCK(); + afs_globalVFS = mp; + *vpp = (struct vnode *) tvp; + tvp->v.v_flag |= VROOT; } - afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *avpp, - ICL_TYPE_INT32, code); + afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp, + ICL_TYPE_INT32, error); AFS_GUNLOCK(); - return code; + return error; } - -mp_afs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg) +int +afs_vget(mp, lfl, vp) +struct mount *mp; +struct vnode *vp; +int lfl; { - return EOPNOTSUPP; + int error; + printf("vget called. help!\n"); + if (vp->v_usecount < 0) { + vprint("bad usecount", vp); + panic("afs_vget"); + } + error = vget(vp, lfl, curproc); + if (!error) + insmntque(vp, afs_globalVFS); /* take off free list */ + return error; } -int mp_afs_statfs(struct mount *afsp) +int afs_statfs(struct mount *mp, struct statfs *abp, struct proc *p) { - struct nstatfs *abp = &afsp->m_stat; - AFS_GLOCK(); AFS_STATCNT(afs_statfs); +#if 0 abp->f_type = MOUNT_AFS; - abp->f_bsize = afsp->vfs_bsize; +#endif + abp->f_bsize = mp->vfs_bsize; + abp->f_iosize = mp->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 @@ -187,299 +185,48 @@ int mp_afs_statfs(struct mount *afsp) */ 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); + abp->f_fsid.val[0] = mp->mnt_stat.f_fsid.val[0]; + abp->f_fsid.val[1] = mp->mnt_stat.f_fsid.val[1]; + if (abp != &mp->mnt_stat) { + abp->f_type = mp->mnt_vfc->vfc_typenum; + memcpy((caddr_t)&abp->f_mntonname[0], (caddr_t)mp->mnt_stat.f_mntonname, MNAMELEN); + memcpy((caddr_t)&abp->f_mntfromname[0], (caddr_t)mp->mnt_stat.f_mntfromname, MNAMELEN); } - 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) +int afs_sync(mp, waitfor, cred, p) +struct mount *mp; +int waitfor; +struct ucred *cred; +struct prioc *p; { - AFS_GLOCK(); - AFS_STATCNT(afs_mountroot); - afsmountroot++; - AFS_GUNLOCK(); - return EINVAL; +return 0; } - -/* 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; +int afs_sysctl() { + return EOPNOTSUPP; } -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; +int afs_init(struct vfsconf *vfc) { + return 0; } -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 */ +struct vfsops afs_vfsops = { + afs_mount, + afs_start, + afs_unmount, + afs_root, + afs_quotactl, + afs_statfs, + afs_sync, + afs_vget, + afs_fhtovp, + afs_vptofh, + afs_init, + afs_sysctl }; - -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/FBSD/osi_vm.c b/src/afs/FBSD/osi_vm.c index 560dfd5..e898014 100644 --- a/src/afs/FBSD/osi_vm.c +++ b/src/afs/FBSD/osi_vm.c @@ -26,7 +26,8 @@ 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 @@ -51,8 +52,9 @@ osi_VM_FlushVCache(avc, slept) struct vcache *avc; int *slept; { -#ifdef SECRETLY_OSF1 - if (avc->vrefCount > 1) + struct vm_object *obj; + struct vnode *vp; + if (VREFCOUNT(avc) > 1) return EBUSY; if (avc->opens) @@ -63,80 +65,25 @@ osi_VM_FlushVCache(avc, slept) return EBUSY; AFS_GUNLOCK(); - ubc_invalidate(((struct vnode *)avc)->v_object, 0, 0, B_INVAL); + vp=avc; + simple_lock(&vp->v_interlock); + if (VOP_GETVOBJECT(vp, &obj) == 0) { + vm_object_page_remove(obj, 0, 0, FALSE); +#if 0 + if (obj->ref_count == 0) { + vgonel(vp,curproc); + simple_lock(&vp->v_interlock); + vp->v_tag=VT_AFS; + SetAfsVnode(vp); + } +#endif + } + simple_unlock(&vp->v_interlock); 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 @@ -146,13 +93,32 @@ void osi_VM_StoreAllSegments(avc) struct vcache *avc; { -#ifdef SECRETLY_OSF1 + struct vnode *vp; + struct vm_object *obj; + int anyio,tries; ReleaseWriteLock(&avc->lock); AFS_GUNLOCK(); - osi_ubc_flush_dirty_and_wait((struct vnode *)avc, 0); + tries=5; + vp=avc; + do { + anyio=0; + simple_lock(&vp->v_interlock); + if (VOP_GETVOBJECT(vp, &obj) == 0 && + (obj->flags & OBJ_MIGHTBEDIRTY)) { + if (!vget(vp, + LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) { + if (VOP_GETVOBJECT(vp, &obj) == 0) { + vm_object_page_clean(obj, 0, 0, OBJPC_SYNC); + anyio = 1; + } + vput(vp); + } + } else { + simple_unlock(&vp->v_interlock); + } + } while (anyio && (--tries > 0)); AFS_GLOCK(); ObtainWriteLock(&avc->lock,94); -#endif /* SECRETLY_OSF1 */ } /* Try to invalidate pages, for "fs flush" or "fs flushv"; or @@ -170,14 +136,38 @@ osi_VM_TryToSmush(avc, acred, sync) struct AFS_UCRED *acred; int sync; { -#ifdef SECRETLY_OSF1 + struct vnode *vp; + struct vm_object *obj; + int anyio, tries; 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); + tries=5; + vp=avc; + do { + anyio=0; + simple_lock(&vp->v_interlock); + if (VOP_GETVOBJECT(vp, &obj) == 0 && + (obj->flags & OBJ_MIGHTBEDIRTY)) { + if (!vget(vp, + LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) { + if (VOP_GETVOBJECT(vp, &obj) == 0) { + vm_object_page_clean(obj, 0, 0, OBJPC_SYNC); + anyio = 1; + } + vput(vp); + } + } else { + simple_unlock(&vp->v_interlock); + } + } while (anyio && (--tries > 0)); + simple_lock(&vp->v_interlock); + if (VOP_GETVOBJECT(vp, &obj) == 0) { + vm_object_page_remove(obj, 0, 0, FALSE); + } + simple_unlock(&vp->v_interlock); + /*vinvalbuf(((struct vnode *)avc),0, NOCRED, curproc, 0,0);*/ AFS_GLOCK(); ObtainWriteLock(&avc->lock,59); -#endif /* SECRETLY_OSF1 */ } /* Purge VM for a file when its callback is revoked. @@ -189,10 +179,17 @@ 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 */ + struct vnode *vp; + struct vm_object *obj; + printf("|"); + vp=avc; + simple_lock(&vp->v_interlock); + if (VOP_GETVOBJECT(vp, &obj) == 0) { + printf("X|"); + vm_object_page_remove(obj, 0, 0, FALSE); + } + simple_unlock(&vp->v_interlock); + /*vinvalbuf(((struct vnode *)avc),0, NOCRED, curproc, 0,0);*/ } /* Purge pages beyond end-of-file, when truncating a file. @@ -207,8 +204,5 @@ osi_VM_Truncate(avc, alen, acred) int alen; struct AFS_UCRED *acred; { -#ifdef SECRETLY_OSF1 - ubc_invalidate(((struct vnode *)avc)->v_object, alen, - MAXINT - alen, B_INVAL); -#endif /* SECRETLY_OSF1 */ + vnode_pager_setsize(((struct vnode *)avc), alen); } diff --git a/src/afs/FBSD/osi_vnodeops.c b/src/afs/FBSD/osi_vnodeops.c index beacd69..f5d85e2 100644 --- a/src/afs/FBSD/osi_vnodeops.c +++ b/src/afs/FBSD/osi_vnodeops.c @@ -1,1095 +1,1148 @@ -/* - * 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" +#include 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 /* Standard vendor system headers */ +#include /* Afs-based standard headers */ +#include /* statistics */ +#include +#include +#include +#include +#include +#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, +extern int afs_pbuf_freecnt; + +int afs_vop_lookup(struct vop_lookup_args *); +int afs_vop_create(struct vop_create_args *); +int afs_vop_mknod(struct vop_mknod_args *); +int afs_vop_open(struct vop_open_args *); +int afs_vop_close(struct vop_close_args *); +int afs_vop_access(struct vop_access_args *); +int afs_vop_getattr(struct vop_getattr_args *); +int afs_vop_setattr(struct vop_setattr_args *); +int afs_vop_read(struct vop_read_args *); +int afs_vop_write(struct vop_write_args *); +int afs_vop_getpages(struct vop_getpages_args *); +int afs_vop_putpages(struct vop_putpages_args *); +int afs_vop_ioctl(struct vop_ioctl_args *); +int afs_vop_poll(struct vop_poll_args *); +int afs_vop_mmap(struct vop_mmap_args *); +int afs_vop_fsync(struct vop_fsync_args *); +int afs_vop_remove(struct vop_remove_args *); +int afs_vop_link(struct vop_link_args *); +int afs_vop_rename(struct vop_rename_args *); +int afs_vop_mkdir(struct vop_mkdir_args *); +int afs_vop_rmdir(struct vop_rmdir_args *); +int afs_vop_symlink(struct vop_symlink_args *); +int afs_vop_readdir(struct vop_readdir_args *); +int afs_vop_readlink(struct vop_readlink_args *); +int afs_vop_inactive(struct vop_inactive_args *); +int afs_vop_reclaim(struct vop_reclaim_args *); +int afs_vop_lock(struct vop_lock_args *); +int afs_vop_unlock(struct vop_unlock_args *); +int afs_vop_bmap(struct vop_bmap_args *); +int afs_vop_strategy(struct vop_strategy_args *); +int afs_vop_print(struct vop_print_args *); +int afs_vop_islocked(struct vop_islocked_args *); +int afs_vop_advlock(struct vop_advlock_args *); + + + +/* Global vfs data structures for AFS. */ +vop_t **afs_vnodeop_p; +struct vnodeopv_entry_desc afs_vnodeop_entries[] = { + { &vop_default_desc, (vop_t *) vop_eopnotsupp }, + { &vop_access_desc, (vop_t *) afs_vop_access }, /* access */ + { &vop_advlock_desc, (vop_t *) afs_vop_advlock }, /* advlock */ + { &vop_bmap_desc, (vop_t *) afs_vop_bmap }, /* bmap */ + { &vop_bwrite_desc, (vop_t *) vop_stdbwrite }, + { &vop_close_desc, (vop_t *) afs_vop_close }, /* close */ + { &vop_createvobject_desc, (vop_t *) vop_stdcreatevobject }, + { &vop_destroyvobject_desc, (vop_t *) vop_stddestroyvobject }, + { &vop_create_desc, (vop_t *) afs_vop_create }, /* create */ + { &vop_fsync_desc, (vop_t *) afs_vop_fsync }, /* fsync */ + { &vop_getattr_desc, (vop_t *) afs_vop_getattr }, /* getattr */ + { &vop_getpages_desc, (vop_t *) afs_vop_getpages }, /* read */ + { &vop_getvobject_desc, (vop_t *) vop_stdgetvobject }, + { &vop_putpages_desc, (vop_t *) afs_vop_putpages }, /* write */ + { &vop_inactive_desc, (vop_t *) afs_vop_inactive }, /* inactive */ + { &vop_islocked_desc, (vop_t *) afs_vop_islocked }, /* islocked */ + { &vop_lease_desc, (vop_t *) vop_null }, + { &vop_link_desc, (vop_t *) afs_vop_link }, /* link */ + { &vop_lock_desc, (vop_t *) afs_vop_lock }, /* lock */ + { &vop_lookup_desc, (vop_t *) afs_vop_lookup }, /* lookup */ + { &vop_mkdir_desc, (vop_t *) afs_vop_mkdir }, /* mkdir */ + { &vop_mknod_desc, (vop_t *) afs_vop_mknod }, /* mknod */ + { &vop_mmap_desc, (vop_t *) afs_vop_mmap }, /* mmap */ + { &vop_open_desc, (vop_t *) afs_vop_open }, /* open */ + { &vop_poll_desc, (vop_t *) afs_vop_poll }, /* select */ + { &vop_print_desc, (vop_t *) afs_vop_print }, /* print */ + { &vop_read_desc, (vop_t *) afs_vop_read }, /* read */ + { &vop_readdir_desc, (vop_t *) afs_vop_readdir }, /* readdir */ + { &vop_readlink_desc, (vop_t *) afs_vop_readlink }, /* readlink */ + { &vop_reclaim_desc, (vop_t *) afs_vop_reclaim }, /* reclaim */ + { &vop_remove_desc, (vop_t *) afs_vop_remove }, /* remove */ + { &vop_rename_desc, (vop_t *) afs_vop_rename }, /* rename */ + { &vop_rmdir_desc, (vop_t *) afs_vop_rmdir }, /* rmdir */ + { &vop_setattr_desc, (vop_t *) afs_vop_setattr }, /* setattr */ + { &vop_strategy_desc, (vop_t *) afs_vop_strategy }, /* strategy */ + { &vop_symlink_desc, (vop_t *) afs_vop_symlink }, /* symlink */ + { &vop_unlock_desc, (vop_t *) afs_vop_unlock }, /* unlock */ + { &vop_write_desc, (vop_t *) afs_vop_write }, /* write */ + { &vop_ioctl_desc, (vop_t *) afs_vop_ioctl }, /* XXX ioctl */ + /*{ &vop_seek_desc, afs_vop_seek },*/ /* seek */ + { NULL, NULL } }; +struct vnodeopv_desc afs_vnodeop_opv_desc = + { &afs_vnodeop_p, afs_vnodeop_entries }; -#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; -} +#define GETNAME() \ + struct componentname *cnp = ap->a_cnp; \ + char *name; \ + MALLOC(name, char *, cnp->cn_namelen+1, M_TEMP, M_WAITOK); \ + memcpy(name, cnp->cn_nameptr, cnp->cn_namelen); \ + name[cnp->cn_namelen] = '\0' -mp_afs_create(ndp, attrs) - struct nameidata *ndp; - struct vattr *attrs; -{ - int code; - AFS_GLOCK(); - code = afs_create(ndp, attrs); - AFS_GUNLOCK(); - return code; -} +#define DROPNAME() FREE(name, M_TEMP) + -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 +afs_vop_lookup(ap) +struct vop_lookup_args /* { + struct vnodeop_desc * a_desc; + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + } */ *ap; { - int code; + int error; + struct vcache *vcp; + struct vnode *vp, *dvp; + register int flags = ap->a_cnp->cn_flags; + int lockparent; /* 1 => lockparent flag is set */ + int wantparent; /* 1 => wantparent or lockparent flag */ + struct proc *p; + GETNAME(); + p=cnp->cn_proc; + lockparent = flags & LOCKPARENT; + wantparent = flags & (LOCKPARENT|WANTPARENT); + + if (ap->a_dvp->v_type != VDIR) { + *ap->a_vpp = 0; + DROPNAME(); + return ENOTDIR; + } + dvp = ap->a_dvp; + if (flags & ISDOTDOT) + VOP_UNLOCK(dvp, 0, p); AFS_GLOCK(); - code = afs_access(avc, amode, acred); + error = afs_lookup((struct vcache *)dvp, name, &vcp, cnp->cn_cred); AFS_GUNLOCK(); - return code; -} + if (error) { + if (flags & ISDOTDOT) + VOP_LOCK(dvp, LK_EXCLUSIVE | LK_RETRY, p); + if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && + (flags & ISLASTCN) && error == ENOENT) + error = EJUSTRETURN; + if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) + cnp->cn_flags |= SAVENAME; + DROPNAME(); + *ap->a_vpp = 0; + return (error); + } + vp = (struct vnode *)vcp; /* always get a node if no error */ + + /* The parent directory comes in locked. We unlock it on return + unless the caller wants it left locked. + we also always return the vnode locked. */ + + if (flags & ISDOTDOT) { + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + /* always return the child locked */ + if (lockparent && (flags & ISLASTCN) && + (error = vn_lock(dvp, LK_EXCLUSIVE, p))) { + vput(vp); + DROPNAME(); + return (error); + } + } else if (vp == dvp) { + /* they're the same; afs_lookup() already ref'ed the leaf. + It came in locked, so we don't need to ref OR lock it */ + } else { + if (!lockparent || !(flags & ISLASTCN)) + VOP_UNLOCK(dvp, 0, p); /* done with parent. */ + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + /* always return the child locked */ + } + *ap->a_vpp = vp; -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; -} + if ((cnp->cn_nameiop == RENAME && wantparent && (flags & ISLASTCN)) || + (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))) + cnp->cn_flags |= SAVENAME; -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; + DROPNAME(); + return error; } -mp_afs_setattr(avc, attrs, acred) - struct vcache *avc; - struct vattr *attrs; - struct AFS_UCRED *acred; +int +afs_vop_create(ap) + struct vop_create_args /* { + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + struct vattr *a_vap; + } */ *ap; { - int code; - AFS_GLOCK(); - code = afs_setattr(avc, attrs, acred); - AFS_GUNLOCK(); - return code; -} + int error = 0; + struct vcache *vcp; + register struct vnode *dvp = ap->a_dvp; + struct proc *p; + GETNAME(); + p=cnp->cn_proc; -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); + error = afs_create((struct vcache *)dvp, name, ap->a_vap, ap->a_vap->va_vaflags & VA_EXCLUSIVE? EXCL : NONEXCL, + ap->a_vap->va_mode, &vcp, + cnp->cn_cred); AFS_GUNLOCK(); - return code; + if (error) { + DROPNAME(); + return(error); + } + + if (vcp) { + *ap->a_vpp = (struct vnode *)vcp; + vn_lock((struct vnode *)vcp, LK_EXCLUSIVE| LK_RETRY, p); + } + else *ap->a_vpp = 0; + + DROPNAME(); + return error; } -mp_afs_remove(ndp) - struct nameidata *ndp; +int +afs_vop_mknod(ap) + struct vop_mknod_args /* { + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + struct vattr *a_vap; + } */ *ap; { - int code; - AFS_GLOCK(); - code = afs_remove(ndp); - AFS_GUNLOCK(); - return code; + return(ENODEV); } -mp_afs_link(avc, ndp) - struct vcache *avc; - struct nameidata *ndp; +#if 0 +static int validate_vops(struct vnode *vp, int after) { - int code; + int ret=0; + struct vnodeopv_entry_desc *this; + for (this=afs_vnodeop_entries; this->opve_op; this++) { + if (vp->v_op[this->opve_op->vdesc_offset] != this->opve_impl) { + if (!ret) { + printf("v_op %d ", after); + vprint("check", vp); + } + ret=1; + printf("For oper %d (%s), func is %p, not %p", + this->opve_op->vdesc_offset, this->opve_op->vdesc_name, + vp->v_op[this->opve_op->vdesc_offset], this->opve_impl); + } + } + return ret; +} +#endif +int +afs_vop_open(ap) + struct vop_open_args /* { + struct vnode *a_vp; + int a_mode; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; +{ + int error; + int bad; + struct vcache *vc = (struct vcache *)ap->a_vp; + bad=0; AFS_GLOCK(); - code = afs_link(avc, ndp); + error = afs_open(&vc, ap->a_mode, ap->a_cred); +#ifdef DIAGNOSTIC + if ((struct vnode *)vc != ap->a_vp) + panic("AFS open changed vnode!"); +#endif + afs_BozonLock(&vc->pvnLock, vc); + osi_FlushPages(vc); + afs_BozonUnlock(&vc->pvnLock, vc); AFS_GUNLOCK(); - return code; + return error; } -mp_afs_rename(fndp, tndp) - struct nameidata *fndp, *tndp; +int +afs_vop_close(ap) + struct vop_close_args /* { + struct vnode *a_vp; + int a_fflag; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { int code; + struct vcache *avc=ap->a_vp; AFS_GLOCK(); - code = afs_rename(fndp, tndp); + if (ap->a_cred) + code=afs_close(avc, ap->a_fflag, ap->a_cred, ap->a_p); + else + code=afs_close(avc, ap->a_fflag, &afs_osi_cred, ap->a_p); + afs_BozonLock(&avc->pvnLock, avc); + osi_FlushPages(avc); /* hold bozon lock, but not basic vnode lock */ + afs_BozonUnlock(&avc->pvnLock, avc); AFS_GUNLOCK(); return code; } -mp_afs_mkdir(ndp, attrs) - struct nameidata *ndp; - struct vattr *attrs; +int +afs_vop_access(ap) + struct vop_access_args /* { + struct vnode *a_vp; + int a_mode; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { int code; AFS_GLOCK(); - code = afs_mkdir(ndp, attrs); + code=afs_access((struct vcache *)ap->a_vp, ap->a_mode, ap->a_cred); AFS_GUNLOCK(); return code; } - -mp_afs_rmdir(ndp) - struct nameidata *ndp; +int +afs_vop_getattr(ap) + struct vop_getattr_args /* { + struct vnode *a_vp; + struct vattr *a_vap; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { int code; AFS_GLOCK(); - code = afs_rmdir(ndp); + code=afs_getattr((struct vcache *)ap->a_vp, ap->a_vap, ap->a_cred); AFS_GUNLOCK(); return code; } - -mp_afs_symlink(ndp, attrs, atargetName) - struct nameidata *ndp; - struct vattr *attrs; - register char *atargetName; +int +afs_vop_setattr(ap) + struct vop_setattr_args /* { + struct vnode *a_vp; + struct vattr *a_vap; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { int code; AFS_GLOCK(); - code = afs_symlink(ndp, attrs, atargetName); + code=afs_setattr((struct vcache *)ap->a_vp, ap->a_vap, ap->a_cred); AFS_GUNLOCK(); return code; -} - -mp_afs_readdir(avc, auio, acred, eofp) - struct vcache *avc; - struct uio *auio; - struct AFS_UCRED *acred; - int *eofp; +}int +afs_vop_read(ap) + struct vop_read_args /* { + struct vnode *a_vp; + struct uio *a_uio; + int a_ioflag; + struct ucred *a_cred; + +} */ *ap; { int code; + struct vcache *avc=(struct vcache *)ap->a_vp; AFS_GLOCK(); - code = afs_readdir(avc, auio, acred, eofp); + afs_BozonLock(&avc->pvnLock, avc); + osi_FlushPages(avc); /* hold bozon lock, but not basic vnode lock */ + code=afs_read(avc, ap->a_uio, ap->a_cred, 0, 0, 0); + afs_BozonUnlock(&avc->pvnLock, avc); AFS_GUNLOCK(); return code; } - -mp_afs_readlink(avc, auio, acred) - struct vcache *avc; - struct uio *auio; - struct AFS_UCRED *acred; +int +afs_vop_getpages(ap) + struct vop_getpages_args /* { + struct vnode *a_vp; + vm_page_t *a_m; + int a_count; + int a_reqpage; + vm_oofset_t a_offset; + } */ *ap; { int code; + int i, nextoff, size, toff, npages; + struct uio uio; + struct iovec iov; + struct buf *bp; + vm_offset_t kva; + struct vcache *avc=(struct vcache *)ap->a_vp; + + if (avc->v.v_object == NULL) { + printf("afs_getpages: called with non-merged cache vnode??\n"); + return VM_PAGER_ERROR; + } + npages=btoc(ap->a_count); + /* + * If the requested page is partially valid, just return it and + * allow the pager to zero-out the blanks. Partially valid pages + * can only occur at the file EOF. + */ + + { + vm_page_t m = ap->a_m[ap->a_reqpage]; + + if (m->valid != 0) { + /* handled by vm_fault now */ + /* vm_page_zero_invalid(m, TRUE); */ + for (i = 0; i < npages; ++i) { + if (i != ap->a_reqpage) + vnode_pager_freepage(ap->a_m[i]); + } + return(0); + } + } + bp = getpbuf(&afs_pbuf_freecnt); + kva = (vm_offset_t) bp->b_data; + pmap_qenter(kva, ap->a_m, npages); + iov.iov_base=(caddr_t)kva; + iov.iov_len=ap->a_count; + uio.uio_iov=&iov; + uio.uio_iovcnt=1; + uio.uio_offset=IDX_TO_OFF(ap->a_m[0]->pindex); + uio.uio_resid=ap->a_count; + uio.uio_segflg=UIO_SYSSPACE; + uio.uio_rw=UIO_READ; + uio.uio_procp=curproc; AFS_GLOCK(); - code = afs_readlink(avc, auio, acred); + afs_BozonLock(&avc->pvnLock, avc); + osi_FlushPages(avc); /* hold bozon lock, but not basic vnode lock */ + code=afs_read(avc, &uio, curproc->p_cred->pc_ucred, 0, 0, 0); + afs_BozonUnlock(&avc->pvnLock, avc); AFS_GUNLOCK(); - return code; + pmap_qremove(kva, npages); + + relpbuf(bp, &afs_pbuf_freecnt); + if (code && (uio.uio_resid == ap->a_count)) { + for (i = 0; i < npages; ++i) { + if (i != ap->a_reqpage) + vnode_pager_freepage(ap->a_m[i]); + } + return VM_PAGER_ERROR; + } + size = ap->a_count - uio.uio_resid; + for (i = 0, toff = 0; i < npages; i++, toff = nextoff) { + vm_page_t m; + nextoff = toff + PAGE_SIZE; + m = ap->a_m[i]; + + m->flags &= ~PG_ZERO; + + if (nextoff <= size) { + /* + * Read operation filled an entire page + */ + m->valid = VM_PAGE_BITS_ALL; + vm_page_undirty(m); + } else if (size > toff) { + /* + * Read operation filled a partial page. + */ + m->valid = 0; + vm_page_set_validclean(m, 0, size - toff); + /* handled by vm_fault now */ + /* vm_page_zero_invalid(m, TRUE); */ + } + + if (i != ap->a_reqpage) { + /* + * Whether or not to leave the page activated is up in + * the air, but we should put the page on a page queue + * somewhere (it already is in the object). Result: + * It appears that emperical results show that + * deactivating pages is best. + */ + + /* + * Just in case someone was asking for this page we + * now tell them that it is ok to use. + */ + if (!code) { + if (m->flags & PG_WANTED) + vm_page_activate(m); + else + vm_page_deactivate(m); + vm_page_wakeup(m); + } else { + vnode_pager_freepage(m); + } + } + } + return 0; } - -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 +afs_vop_write(ap) + struct vop_write_args /* { + struct vnode *a_vp; + struct uio *a_uio; + int a_ioflag; + struct ucred *a_cred; + } */ *ap; { int code; + struct vcache *avc=(struct vcache *)ap->a_vp; AFS_GLOCK(); - code = afs_lockctl(avc, af, flag, acred, clid, offset); + afs_BozonLock(&avc->pvnLock, avc); + osi_FlushPages(avc); /* hold bozon lock, but not basic vnode lock */ + code=afs_write((struct vcache *)ap->a_vp, ap->a_uio, ap->a_ioflag, ap->a_cred, 0); + afs_BozonUnlock(&avc->pvnLock, avc); AFS_GUNLOCK(); return code; } -mp_afs_closex(afd) - struct file *afd; +int +afs_vop_putpages(ap) + struct vop_putpages_args /* { + struct vnode *a_vp; + vm_page_t *a_m; + int a_count; + int a_sync; + int *a_rtvals; + vm_oofset_t a_offset; + } */ *ap; { int code; + int i, size, npages, sync; + struct uio uio; + struct iovec iov; + struct buf *bp; + vm_offset_t kva; + struct vcache *avc=(struct vcache *)ap->a_vp; + + if (avc->v.v_object == NULL) { + printf("afs_putpages: called with non-merged cache vnode??\n"); + return VM_PAGER_ERROR; + } + if (vType(avc) != VREG) { + printf("afs_putpages: not VREG"); + return VM_PAGER_ERROR; + } + npages=btoc(ap->a_count); + for (i=0; i < npages; i++ ) ap->a_rtvals[i]=VM_PAGER_AGAIN; + bp = getpbuf(&afs_pbuf_freecnt); + kva = (vm_offset_t) bp->b_data; + pmap_qenter(kva, ap->a_m, npages); + iov.iov_base=(caddr_t)kva; + iov.iov_len=ap->a_count; + uio.uio_iov=&iov; + uio.uio_iovcnt=1; + uio.uio_offset=IDX_TO_OFF(ap->a_m[0]->pindex); + uio.uio_resid=ap->a_count; + uio.uio_segflg=UIO_SYSSPACE; + uio.uio_rw=UIO_WRITE; + uio.uio_procp=curproc; + sync=IO_VMIO; + if (ap->a_sync & VM_PAGER_PUT_SYNC) + sync|=IO_SYNC; + /*if (ap->a_sync & VM_PAGER_PUT_INVAL) + sync|=IO_INVAL;*/ + AFS_GLOCK(); - code = afs_closex(afd); + afs_BozonLock(&avc->pvnLock, avc); + code=afs_write(avc, &uio, sync, curproc->p_cred->pc_ucred, 0); + afs_BozonUnlock(&avc->pvnLock, avc); 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); -} + pmap_qremove(kva, npages); -mp_afs_abortop(ndp) - struct nameidata *ndp; -{ - return(0); + relpbuf(bp, &afs_pbuf_freecnt); + if (!code) { + size = ap->a_count - uio.uio_resid; + for (i = 0; i < round_page(size) / PAGE_SIZE; i++) { + ap->a_rtvals[i]=VM_PAGER_OK; + ap->a_m[i]->dirty=0; + } + return VM_PAGER_ERROR; + } + return ap->a_rtvals[0]; } - -mp_afs_inactive(avc, acred) - register struct vcache *avc; - struct AFS_UCRED *acred; +int +afs_vop_ioctl(ap) + struct vop_ioctl_args /* { + struct vnode *a_vp; + int a_command; + caddr_t a_data; + int a_fflag; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { + struct vcache *tvc = (struct vcache *)ap->a_vp; + struct afs_ioctl data; + int error = 0; + + /* in case we ever get in here... */ + + AFS_STATCNT(afs_ioctl); + if (((ap->a_command >> 8) & 0xff) == 'V') { + /* This is a VICEIOCTL call */ AFS_GLOCK(); - afs_InactiveVCache(avc, acred); + error = HandleIoctl(tvc, (struct file *)0/*Not used*/, + ap->a_command, ap->a_data); AFS_GUNLOCK(); + return(error); + } else { + /* No-op call; just return. */ + return(ENOTTY); + } } - -mp_afs_reclaim(avc) - struct vcache *avc; +/* ARGSUSED */ +int +afs_vop_poll(ap) + struct vop_poll_args /* { + struct vnode *a_vp; + int a_events; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { - return(0); + /* + * We should really check to see if I/O is possible. + */ + return (1); } - -mp_afs_print(avc) - struct vcache *avc; +/* + * Mmap a file + * + * NB Currently unsupported. + */ +/* ARGSUSED */ +int +afs_vop_mmap(ap) + struct vop_mmap_args /* { + struct vnode *a_vp; + int a_fflags; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; { - return(0); + return (EINVAL); } -mp_afs_page_read(avc, uio, acred) - struct vcache *avc; - struct uio *uio; - struct ucred *acred; +int +afs_vop_fsync(ap) + struct vop_fsync_args /* { + struct vnode *a_vp; + struct ucred *a_cred; + int a_waitfor; + struct proc *a_p; + } */ *ap; { + int wait = ap->a_waitfor == MNT_WAIT; int error; - struct vrequest treq; + register struct vnode *vp = ap->a_vp; 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); - } + /*vflushbuf(vp, wait);*/ + if (ap->a_cred) + error=afs_fsync((struct vcache *)vp, ap->a_cred); + else + error=afs_fsync((struct vcache *)vp, &afs_osi_cred); AFS_GUNLOCK(); - return(error); + 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 +afs_vop_remove(ap) + struct vop_remove_args /* { + struct vnode *a_dvp; + struct vnode *a_vp; + struct componentname *a_cnp; + } */ *ap; { - int error; + int error = 0; + register struct vnode *vp = ap->a_vp; + register struct vnode *dvp = ap->a_dvp; + GETNAME(); 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; - } + error = afs_remove((struct vcache *)dvp, name, cnp->cn_cred); AFS_GUNLOCK(); - return(error); + cache_purge(vp); + DROPNAME(); + return error; } - -int DO_FLUSH=1; -mp_afs_ubcrdwr(avc, uio, ioflag, cred) - struct vcache *avc; - struct uio *uio; - int ioflag; - struct ucred *cred; +int +afs_vop_link(ap) + struct vop_link_args /* { + struct vnode *a_vp; + struct vnode *a_tdvp; + struct componentname *a_cnp; + } */ *ap; { - 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; + int error = 0; + register struct vnode *dvp = ap->a_tdvp; + register struct vnode *vp = ap->a_vp; + struct proc *p; + + GETNAME(); + p=cnp->cn_proc; + if (dvp->v_mount != vp->v_mount) { + error = EXDEV; + goto out; } - 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 (vp->v_type == VDIR) { + error = EISDIR; + goto out; } - 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(); + if (error = vn_lock(vp, LK_EXCLUSIVE, p)) { + goto out; } + AFS_GLOCK(); + error = afs_link((struct vcache *)vp, (struct vcache *)dvp, name, cnp->cn_cred); + AFS_GUNLOCK(); + if (dvp != vp) + VOP_UNLOCK(vp,0, p); +out: + DROPNAME(); + return error; +} - 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. +int +afs_vop_rename(ap) + struct vop_rename_args /* { + struct vnode *a_fdvp; + struct vnode *a_fvp; + struct componentname *a_fcnp; + struct vnode *a_tdvp; + struct vnode *a_tvp; + struct componentname *a_tcnp; + } */ *ap; +{ + int error = 0; + struct componentname *fcnp = ap->a_fcnp; + char *fname; + struct componentname *tcnp = ap->a_tcnp; + char *tname; + struct vnode *tvp = ap->a_tvp; + register struct vnode *tdvp = ap->a_tdvp; + struct vnode *fvp = ap->a_fvp; + register struct vnode *fdvp = ap->a_fdvp; + struct proc *p=fcnp->cn_proc; + + /* + * Check for cross-device rename. */ - if (code == EDQUOT || code == ENOSPC) { - uio->uio_resid = save_resid; - UpgradeSToWLock(&avc->lock, 410); - osi_ReleaseVM(avc, cred); - ConvertWToSLock(&avc->lock); + if ((fvp->v_mount != tdvp->v_mount) || + (tvp && (fvp->v_mount != tvp->v_mount))) { + error = EXDEV; +abortit: + if (tdvp == tvp) + vrele(tdvp); + else + vput(tdvp); + if (tvp) + vput(tvp); + vrele(fdvp); + vrele(fvp); + return (error); } - ReleaseSharedLock(&avc->lock); + /* + * if fvp == tvp, we're just removing one name of a pair of + * directory entries for the same element. convert call into rename. + ( (pinched from FreeBSD 4.4's ufs_rename()) + + */ + if (fvp == tvp) { + if (fvp->v_type == VDIR) { + error = EINVAL; + goto abortit; + } - if (!code && (ioflag & IO_SYNC) && (uio->uio_rw == UIO_WRITE) - && !AFS_NFSXLATORREQ(cred)) { - code = afs_fsync(avc, 0, cred, 0); + /* Release destination completely. */ + vput(tdvp); + vput(tvp); + + /* Delete source. */ + vrele(fdvp); + vrele(fvp); + fcnp->cn_flags &= ~MODMASK; + fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; + if ((fcnp->cn_flags & SAVESTART) == 0) + panic("afs_rename: lost from startdir"); + fcnp->cn_nameiop = DELETE; + VREF(fdvp); + error=relookup(fdvp, &fvp, fcnp); + if (error == 0) + vrele(fdvp); + if (fvp == NULL) { + return (ENOENT); + } + + error=VOP_REMOVE(fdvp, fvp, fcnp); + if (fdvp == fvp) + vrele(fdvp); + else + vput(fdvp); + vput(fvp); + return (error); } -out: - code = afs_CheckCode(code, &treq, 36); - AFS_GUNLOCK(); - return code; -} + if (error = vn_lock(fvp, LK_EXCLUSIVE, p)) + goto abortit; + MALLOC(fname, char *, fcnp->cn_namelen+1, M_TEMP, M_WAITOK); + memcpy(fname, fcnp->cn_nameptr, fcnp->cn_namelen); + fname[fcnp->cn_namelen] = '\0'; + MALLOC(tname, char *, tcnp->cn_namelen+1, M_TEMP, M_WAITOK); + memcpy(tname, tcnp->cn_nameptr, tcnp->cn_namelen); + tname[tcnp->cn_namelen] = '\0'; -/* - * 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; + /* XXX use "from" or "to" creds? NFS uses "to" creds */ + error = afs_rename((struct vcache *)fdvp, fname, (struct vcache *)tdvp, tname, tcnp->cn_cred); 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; -} + FREE(fname, M_TEMP); + FREE(tname, M_TEMP); + if (tdvp == tvp) + vrele(tdvp); + else + vput(tdvp); + if (tvp) + vput(tvp); + vrele(fdvp); + vput(fvp); + return error; +} -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; +int +afs_vop_mkdir(ap) + struct vop_mkdir_args /* { + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + struct vattr *a_vap; + } */ *ap; { - 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 */ - + register struct vnode *dvp = ap->a_dvp; + register struct vattr *vap = ap->a_vap; + int error = 0; + struct vcache *vcp; + struct proc *p; + + GETNAME(); + p=cnp->cn_proc; +#ifdef DIAGNOSTIC + if ((cnp->cn_flags & HASBUF) == 0) + panic("afs_vop_mkdir: no name"); +#endif 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 */ + error = afs_mkdir((struct vcache *)dvp, name, vap, &vcp, cnp->cn_cred); 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; - } - } + if (error) { + vput(dvp); + DROPNAME(); + return(error); } -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; + if (vcp) { + *ap->a_vpp = (struct vnode *)vcp; + vn_lock((struct vnode *)vcp, LK_EXCLUSIVE|LK_RETRY, p); + } else + *ap->a_vpp = 0; + DROPNAME(); + return error; } - -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; +int +afs_vop_rmdir(ap) + struct vop_rmdir_args /* { + struct vnode *a_dvp; + struct vnode *a_vp; + struct componentname *a_cnp; + } */ *ap; { - register afs_int32 code=0; - struct vcache *avc = (struct vcache *)vop->vu_vp; - struct vnode *vp = (struct vnode *)avc; - int i; + int error = 0; + register struct vnode *vp = ap->a_vp; + register struct vnode *dvp = ap->a_dvp; + GETNAME(); 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); + error = afs_rmdir((struct vcache *)dvp, name, cnp->cn_cred); AFS_GUNLOCK(); - return code; + DROPNAME(); + return error; } - -int mp_afs_swap(avc, swapop, argp) - struct vcache *avc; - vp_swap_op_t swapop; - vm_offset_t argp; +int +afs_vop_symlink(ap) + struct vop_symlink_args /* { + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + struct vattr *a_vap; + char *a_target; + } */ *ap; { - return EIO; -} + register struct vnode *dvp = ap->a_dvp; + int error = 0; + /* NFS ignores a_vpp; so do we. */ -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; + GETNAME(); + AFS_GLOCK(); + error = afs_symlink((struct vcache *)dvp, name, ap->a_vap, ap->a_target, + cnp->cn_cred); + AFS_GUNLOCK(); + DROPNAME(); + return error; } -/* 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 +afs_vop_readdir(ap) + struct vop_readdir_args /* { + struct vnode *a_vp; + struct uio *a_uio; + struct ucred *a_cred; + int *a_eofflag; + u_long *a_cookies; + int ncookies; + } */ *ap; { - 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); + int error; + off_t off; +/* printf("readdir %x cookies %x ncookies %d\n", ap->a_vp, ap->a_cookies, + ap->a_ncookies); */ + off=ap->a_uio->uio_offset; + AFS_GLOCK(); + error= afs_readdir((struct vcache *)ap->a_vp, ap->a_uio, ap->a_cred, + ap->a_eofflag); + AFS_GUNLOCK(); + if (!error && ap->a_ncookies != NULL) { + struct uio *uio = ap->a_uio; + const struct dirent *dp, *dp_start, *dp_end; + int ncookies; + u_long *cookies, *cookiep; + + if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) + panic("afs_readdir: burned cookies"); + dp = (const struct dirent *) + ((const char *)uio->uio_iov->iov_base - (uio->uio_offset - off)); + + dp_end = (const struct dirent *) uio->uio_iov->iov_base; + for (dp_start = dp, ncookies = 0; + dp < dp_end; + dp = (const struct dirent *)((const char *) dp + dp->d_reclen)) + ncookies++; + + MALLOC(cookies, u_long *, ncookies * sizeof(u_long), + M_TEMP, M_WAITOK); + for (dp = dp_start, cookiep = cookies; + dp < dp_end; + dp = (const struct dirent *)((const char *) dp + dp->d_reclen)) { + off += dp->d_reclen; + *cookiep++ = off; } + *ap->a_cookies = cookies; + *ap->a_ncookies = ncookies; + } - 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; + return error; } - -mp_afs_brelse(vp, bp) -struct vnode *vp; -struct buf *bp; +int +afs_vop_readlink(ap) + struct vop_readlink_args /* { + struct vnode *a_vp; + struct uio *a_uio; + struct ucred *a_cred; + } */ *ap; { + int error; +/* printf("readlink %x\n", ap->a_vp);*/ 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; - } + error= afs_readlink((struct vcache *)ap->a_vp, ap->a_uio, ap->a_cred); AFS_GUNLOCK(); + return error; } +extern int prtactive; -mp_afs_bmap(avc, abn, anvp, anbn) - register struct vcache *avc; - afs_int32 abn, *anbn; - struct vcache **anvp; +int +afs_vop_inactive(ap) + struct vop_inactive_args /* { + struct vnode *a_vp; + struct proc *a_p; + } */ *ap; { + register struct vnode *vp = ap->a_vp; + + if (prtactive && vp->v_usecount != 0) + vprint("afs_vop_inactive(): pushing active", vp); + AFS_GLOCK(); - AFS_STATCNT(afs_bmap); - if (anvp) - *anvp = avc; - if (anbn) - *anbn = abn * (8192 / DEV_BSIZE); /* in 512 byte units */ + afs_InactiveVCache((struct vcache *)vp, 0); /* decrs ref counts */ AFS_GUNLOCK(); + VOP_UNLOCK(vp, 0, ap->a_p); return 0; } - -/* real strategy */ -mp_afs_strategy (abp) - register struct buf *abp; +int +afs_vop_reclaim(ap) + struct vop_reclaim_args /* { + struct vnode *a_vp; + } */ *ap; { - register afs_int32 code; + int error; + int sl; + register struct vnode *vp = ap->a_vp; + + cache_purge(vp); /* just in case... */ +#if 0 AFS_GLOCK(); - AFS_STATCNT(afs_strategy); - code = afs_osi_MapStrategy(afs_ustrategy, abp); + error = afs_FlushVCache((struct vcache *)vp, &sl); /* tosses our stuff from vnode */ AFS_GUNLOCK(); - return code; + ubc_unlink(vp); + if (!error && vp->v_data) + panic("afs_reclaim: vnode not cleaned"); + return error; +#else + if (vp->v_usecount == 2) { + vprint("reclaim count==2", vp); + } else if (vp->v_usecount == 1) { + vprint("reclaim count==1", vp); + } else + vprint("reclaim bad count", vp); + + return 0; +#endif } - -mp_afs_refer(vm_ubc_object_t vop) +int +afs_vop_lock(ap) + struct vop_lock_args /* { + struct vnode *a_vp; + } */ *ap; { - VREF(vop->vu_vp); -} + register struct vnode *vp = ap->a_vp; + register struct vcache *avc = (struct vcache *)vp; + if (vp->v_tag == VT_NON) + return (ENOENT); + return (lockmgr(&avc->rwlock, ap->a_flags, &vp->v_interlock, + ap->a_p)); +} -mp_afs_release(vm_ubc_object_t vop) +int +afs_vop_unlock(ap) + struct vop_unlock_args /* { + struct vnode *a_vp; + } */ *ap; { - vrele(vop->vu_vp); -} + struct vnode *vp = ap->a_vp; + struct vcache *avc = (struct vcache *)vp; + return (lockmgr(&avc->rwlock, ap->a_flags | LK_RELEASE, + &vp->v_interlock, ap->a_p)); +} -mp_afs_write_check(vm_ubc_object_t vop, vm_page_t pp) +int +afs_vop_bmap(ap) + struct vop_bmap_args /* { + struct vnode *a_vp; + daddr_t a_bn; + struct vnode **a_vpp; + daddr_t *a_bnp; + int *a_runp; + int *a_runb; + } */ *ap; { - return TRUE; + struct vcache *vcp; + int error; + if (ap->a_bnp) { + *ap->a_bnp = ap->a_bn * (PAGE_SIZE / DEV_BSIZE); + } + if (ap->a_vpp) { + *ap->a_vpp = ap->a_vp; + } + if (ap->a_runp != NULL) + *ap->a_runp = 0; + if (ap->a_runb != NULL) + *ap->a_runb = 0; + + return 0; +} +int +afs_vop_strategy(ap) + struct vop_strategy_args /* { + struct buf *a_bp; + } */ *ap; +{ + int error; + AFS_GLOCK(); + error= afs_ustrategy(ap->a_bp); + AFS_GUNLOCK(); + return error; +} +int +afs_vop_print(ap) + struct vop_print_args /* { + struct vnode *a_vp; + } */ *ap; +{ + register struct vnode *vp = ap->a_vp; + register struct vcache *vc = (struct vcache *)ap->a_vp; + int s = vc->states; + printf("tag %d, fid: %ld.%x.%x.%x, opens %d, writers %d", vp->v_tag, vc->fid.Cell, + vc->fid.Fid.Volume, vc->fid.Fid.Vnode, vc->fid.Fid.Unique, vc->opens, + vc->execsOrWriters); + printf("\n states%s%s%s%s%s", (s&CStatd) ? " statd" : "", (s&CRO) ? " readonly" : "",(s&CDirty) ? " dirty" : "",(s&CMAPPED) ? " mapped" : "", (s&CVFlushed) ? " flush in progress" : ""); + printf("\n"); + return 0; } - - -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 */ +int +afs_vop_islocked(ap) + struct vop_islocked_args /* { + struct vnode *a_vp; + } */ *ap; +{ + struct vcache *vc = (struct vcache *)ap->a_vp; + return lockstatus(&vc->rwlock, ap->a_p); +} /* - * 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. + * Advisory record locking support (fcntl() POSIX style) */ -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 */ +int +afs_vop_advlock(ap) + struct vop_advlock_args /* { + struct vnode *a_vp; + caddr_t a_id; + int a_op; + struct flock *a_fl; + int a_flags; + } */ *ap; { - /* 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); + struct proc *p=curproc; + struct ucred cr; + cr=*p->p_cred->pc_ucred; + AFS_GLOCK(); + error= afs_lockctl((struct vcache *)ap->a_vp, ap->a_fl, ap->a_op, &cr, + (int) ap->a_id); + AFS_GUNLOCK(); + return error; } diff --git a/src/afs/FBSD/vnode_if.h b/src/afs/FBSD/vnode_if.h index 7c4da8f..ded87a1 100644 --- a/src/afs/FBSD/vnode_if.h +++ b/src/afs/FBSD/vnode_if.h @@ -1,13 +1,4 @@ /* - * 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 - */ - -/* * This file is produced automatically. * Do not modify anything in here by hand. * @@ -467,6 +458,27 @@ static __inline int VOP_POLL(vp, events, cred, p) rc = VCALL(vp, VOFFSET(vop_poll), &a); return (rc); } +struct vop_kqfilter_args { + struct vnodeop_desc *a_desc; + struct vnode *a_vp; + struct knote *a_kn; +}; +extern struct vnodeop_desc vop_kqfilter_desc; +static __inline int VOP_KQFILTER __P(( + struct vnode *vp, + struct knote *kn)); +static __inline int VOP_KQFILTER(vp, kn) + struct vnode *vp; + struct knote *kn; +{ + struct vop_kqfilter_args a; + int rc; + a.a_desc = VDESC(vop_kqfilter); + a.a_vp = vp; + a.a_kn = kn; + rc = VCALL(vp, VOFFSET(vop_kqfilter), &a); + return (rc); +} struct vop_revoke_args { struct vnodeop_desc *a_desc; struct vnode *a_vp; @@ -1346,3 +1358,66 @@ static __inline int VOP_SETEXTATTR(vp, name, uio, cred, p) rc = VCALL(vp, VOFFSET(vop_setextattr), &a); return (rc); } +struct vop_createvobject_args { + struct vnodeop_desc *a_desc; + struct vnode *a_vp; + struct ucred *a_cred; + struct proc *a_p; +}; +extern struct vnodeop_desc vop_createvobject_desc; +static __inline int VOP_CREATEVOBJECT __P(( + struct vnode *vp, + struct ucred *cred, + struct proc *p)); +static __inline int VOP_CREATEVOBJECT(vp, cred, p) + struct vnode *vp; + struct ucred *cred; + struct proc *p; +{ + struct vop_createvobject_args a; + int rc; + a.a_desc = VDESC(vop_createvobject); + a.a_vp = vp; + a.a_cred = cred; + a.a_p = p; + rc = VCALL(vp, VOFFSET(vop_createvobject), &a); + return (rc); +} +struct vop_destroyvobject_args { + struct vnodeop_desc *a_desc; + struct vnode *a_vp; +}; +extern struct vnodeop_desc vop_destroyvobject_desc; +static __inline int VOP_DESTROYVOBJECT __P(( + struct vnode *vp)); +static __inline int VOP_DESTROYVOBJECT(vp) + struct vnode *vp; +{ + struct vop_destroyvobject_args a; + int rc; + a.a_desc = VDESC(vop_destroyvobject); + a.a_vp = vp; + rc = VCALL(vp, VOFFSET(vop_destroyvobject), &a); + return (rc); +} +struct vop_getvobject_args { + struct vnodeop_desc *a_desc; + struct vnode *a_vp; + struct vm_object **a_objpp; +}; +extern struct vnodeop_desc vop_getvobject_desc; +static __inline int VOP_GETVOBJECT __P(( + struct vnode *vp, + struct vm_object **objpp)); +static __inline int VOP_GETVOBJECT(vp, objpp) + struct vnode *vp; + struct vm_object **objpp; +{ + struct vop_getvobject_args a; + int rc; + a.a_desc = VDESC(vop_getvobject); + a.a_vp = vp; + a.a_objpp = objpp; + rc = VCALL(vp, VOFFSET(vop_getvobject), &a); + return (rc); +} diff --git a/src/afs/VNOPS/afs_vnop_attrs.c b/src/afs/VNOPS/afs_vnop_attrs.c index 48b878a..6e191c5 100644 --- a/src/afs/VNOPS/afs_vnop_attrs.c +++ b/src/afs/VNOPS/afs_vnop_attrs.c @@ -101,7 +101,17 @@ afs_CopyOutAttrs(avc, attrs) * anyway, so the difference between 512K and 1000000 shouldn't matter * much, and "&" is a lot faster than "%". */ -#if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) + /* nfs on these systems puts an 0 in nsec and stores the nfs usec (aka + dataversion) in va_gen */ + + attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec = + attrs->va_ctime.tv_nsec =0; + attrs->va_blocksize = PAGESIZE; /* XXX Was 8192 XXX */ + attrs->va_gen = hgetlo(avc->m.DataVersion); + attrs->va_flags = 0; +#else +#if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec = attrs->va_ctime.tv_nsec = (hgetlo(avc->m.DataVersion) & 0x7ffff) * 1000; @@ -116,6 +126,7 @@ afs_CopyOutAttrs(avc, attrs) (hgetlo(avc->m.DataVersion) & 0x7ffff); attrs->va_blocksize = PAGESIZE; /* XXX Was 8192 XXX */ #endif +#endif #ifdef AFS_DEC_ENV /* Have to use real device #s in Ultrix, since that's how FS type is * encoded. If rdev doesn't match Ultrix equivalent of statfs's rdev, then @@ -132,7 +143,7 @@ afs_CopyOutAttrs(avc, attrs) * Below return 0 (and not 1) blocks if the file is zero length. This conforms * better with the other filesystems that do return 0. */ -#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) +#if defined(AFS_OSF_ENV) #ifdef va_size_rsv attrs->va_size_rsv = 0; #endif diff --git a/src/afs/VNOPS/afs_vnop_flock.c b/src/afs/VNOPS/afs_vnop_flock.c index 2509052..aba1303 100644 --- a/src/afs/VNOPS/afs_vnop_flock.c +++ b/src/afs/VNOPS/afs_vnop_flock.c @@ -37,7 +37,7 @@ RCSID("$Header$"); static int GetFlockCount(struct vcache *avc, struct vrequest *areq); void lockIdSet(flock, slp, clid) - int clid; /* non-zero on SGI, OSF, SunOS */ + int clid; /* non-zero on SGI, OSF, SunOS, Darwin, xBSD *//* XXX ptr type */ struct SimpleLocks *slp; struct AFS_FLOCK *flock; { @@ -175,10 +175,11 @@ static int lockIdcmp2(flock1, vp, alp, onlymine, clid) } #endif if ((flock1->l_pid == alp->pid) || -#if defined(AFS_AIX41_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_AIX41_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_HPUX_ENV) (!onlymine && (flock1->l_pid == getppid())) #else -#if defined(AFS_SGI65_ENV) +#if defined(AFS_SGI65_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) + /* XXX check this. used to be *only* irix for some reason. */ (!onlymine && (flock1->l_pid == clid)) #else (!onlymine && (flock1->l_pid == procp->p_ppid)) @@ -865,11 +866,7 @@ afs_xflock () { uap = (struct a *)args; getf(&fd, uap->fd, FILE_FLAGS_NULL, &u.u_file_state); #else /* AFS_OSF_ENV */ -#if defined(AFS_FBSD_ENV) - uap = (struct a *)u.u_ap; -#else uap = (struct a *)u.u_ap; -#endif /* AFS_FBSD_ENV */ fd = getf(uap->fd); #endif if (!fd) return; diff --git a/src/afs/VNOPS/afs_vnop_read.c b/src/afs/VNOPS/afs_vnop_read.c index a0222f4..9ce8903 100644 --- a/src/afs/VNOPS/afs_vnop_read.c +++ b/src/afs/VNOPS/afs_vnop_read.c @@ -535,6 +535,13 @@ afs_UFSReadFast(avc, auio, acred, albn, abpp, noLock) VOP_UNLOCK(tfile->vnode, 0, current_proc()); AFS_GLOCK(); #else +#if defined(AFS_FBSD_ENV) + AFS_GUNLOCK(); + VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curproc); + code = VOP_READ(tfile->vnode, auio, 0, &afs_osi_cred); + VOP_UNLOCK(tfile->vnode, 0, curproc); + AFS_GLOCK(); +#else code = VOP_RDWR(tfile->vnode, auio, UIO_READ, 0, &afs_osi_cred); #endif #endif @@ -543,6 +550,7 @@ afs_UFSReadFast(avc, auio, acred, albn, abpp, noLock) #endif #endif #endif +#endif auio->afsio_offset += avc->quick.minLoc; osi_UFSClose(tfile); /* Fix up LRU info */ @@ -926,6 +934,13 @@ tagain: VOP_UNLOCK(tfile->vnode, 0, current_proc()); AFS_GLOCK(); #else +#if defined(AFS_FBSD_ENV) + AFS_GUNLOCK(); + VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curproc); + code = VOP_READ(tfile->vnode, auio, 0, &afs_osi_cred); + VOP_UNLOCK(tfile->vnode, 0, curproc); + AFS_GLOCK(); +#else code = VOP_RDWR(tfile->vnode, &tuio, UIO_READ, 0, &afs_osi_cred); #endif #endif @@ -935,6 +950,7 @@ tagain: #endif #endif #endif +#endif #ifdef IHINT if (!tdc->ihint && nihints < maxIHint) { diff --git a/src/afs/VNOPS/afs_vnop_readdir.c b/src/afs/VNOPS/afs_vnop_readdir.c index 9c024a1..71b86fe 100644 --- a/src/afs/VNOPS/afs_vnop_readdir.c +++ b/src/afs/VNOPS/afs_vnop_readdir.c @@ -140,7 +140,7 @@ struct irix5_min_dirent { /* miniature dirent structure */ #else struct min_direct { /* miniature direct structure */ /* If struct direct changes, this must too */ -#ifdef AFS_DARWIN_ENV +#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) afs_uint32 d_fileno; u_short d_reclen; u_char d_type; @@ -226,6 +226,45 @@ int afs_rd_stash_i = 0; #endif /* AFS_SUN56_ENV */ #endif /* AFS_HPUX100_ENV */ +#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +int afs_readdir_type(avc, ade) +struct DirEntry * ade; +struct vcache * avc; +{ + struct VenusFid tfid; + struct vcache *tvc; + int vtype; + tfid.Cell=avc->fid.Cell; + tfid.Fid.Volume=avc->fid.Fid.Volume; + tfid.Fid.Vnode=ntohl(ade->fid.vnode); + tfid.Fid.Unique=ntohl(ade->fid.vunique); + if ((avc->states & CForeign) == 0 && + (ntohl(ade->fid.vnode) & 1)) { + return DT_DIR; + } else if ((tvc=afs_FindVCache(&tfid,0,0,0,0))) { + if (tvc->mvstat) { + afs_PutVCache(tvc, WRITE_LOCK); + return DT_DIR; + } else if (((tvc->states) & (CStatd|CTruth))) { + /* CTruth will be set if the object has + *ever* been statd */ + vtype=vType(tvc); + afs_PutVCache(tvc, WRITE_LOCK); + if (vtype == VDIR) + return DT_DIR; + else if (vtype == VREG) + return DT_REG; + /* Don't do this until we're sure it can't be a mtpt */ + /* else if (vtype == VLNK) + type=DT_LNK; */ + /* what other types does AFS support? */ + } else + afs_PutVCache(tvc, WRITE_LOCK); + } + return DT_UNKNOWN; +} +#endif + #ifdef AFS_AIX41_ENV #define AFS_MOVE_LOCK() AFS_GLOCK() #define AFS_MOVE_UNLOCK() AFS_GUNLOCK() @@ -233,7 +272,6 @@ int afs_rd_stash_i = 0; #define AFS_MOVE_LOCK() #define AFS_MOVE_UNLOCK() #endif - char bufofzeros[64]; /* gotta fill with something */ afs_readdir_move (de, vc, auio, slen, rlen, off) struct DirEntry * de; @@ -348,8 +386,8 @@ afs_size_t off; #if defined(AFS_SUN_ENV) || defined(AFS_AIX32_ENV) || defined(AFS_SGI_ENV) sdirEntry.d_off = off; #endif -#if defined(AFS_DARWIN_ENV) - sdirEntry.d_type=DT_UNKNOWN; +#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) + sdirEntry.d_type=afs_readdir_type(vc, de); #endif #if defined(AFS_SGI_ENV) @@ -423,7 +461,7 @@ void afs_bulkstat_send( avc, req ) * It has to do with 'offset' (seek locations). */ -#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) +#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) afs_readdir(OSI_VC_ARG(avc), auio, acred, eofp) int *eofp; #else @@ -482,7 +520,7 @@ afs_readdir(OSI_VC_ARG(avc), auio, acred) #endif /* AFS_SGI61_ENV */ #endif /* defined(AFS_SGI53_ENV) */ -#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) +#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) /* Not really used by the callee so we ignore it for now */ if (eofp) *eofp = 0; #endif @@ -615,7 +653,7 @@ tagain: } else { /* nothin to hand over */ } -#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) +#if defined(AFS_SUN5_ENV) || defined(AFS_SGI_ENV) || defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) if (eofp) *eofp = 1; /* Set it properly */ #endif if (ode) DRelease(ode, 0); diff --git a/src/afs/VNOPS/afs_vnop_strategy.c b/src/afs/VNOPS/afs_vnop_strategy.c index 55755c1..ff16704 100644 --- a/src/afs/VNOPS/afs_vnop_strategy.c +++ b/src/afs/VNOPS/afs_vnop_strategy.c @@ -181,12 +181,13 @@ afs_ustrategy(abp) #endif } #if !defined(AFS_AIX32_ENV) && !defined(AFS_SUN5_ENV) -#ifdef AFS_DUX40_ENV +#if defined(AFS_DUX40_ENV) || defined (AFS_FBSD_ENV) if (code) { abp->b_error = code; abp->b_flags |= B_ERROR; } biodone(abp); +#if defined(AFS_DUX40_ENV) if (code && !(abp->b_flags & B_READ)) { /* prevent ubc from retrying writes */ AFS_GUNLOCK(); @@ -195,6 +196,7 @@ afs_ustrategy(abp) PAGE_SIZE, B_INVAL); AFS_GLOCK(); } +#endif #else /* AFS_DUX40_ENV */ iodone(abp); #endif /* AFS_DUX40_ENV */ diff --git a/src/afs/VNOPS/afs_vnop_write.c b/src/afs/VNOPS/afs_vnop_write.c index be9ed95..193f7aa 100644 --- a/src/afs/VNOPS/afs_vnop_write.c +++ b/src/afs/VNOPS/afs_vnop_write.c @@ -554,15 +554,23 @@ afs_UFSWrite(avc, auio, aio, acred, noLock) code = osi_file_uio_rdwr(tfile, &tuio, UIO_WRITE); AFS_GLOCK(); #else -#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_DARWIN_ENV) AFS_GUNLOCK(); VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, current_proc()); code = VOP_WRITE(tfile->vnode, &tuio, 0, &afs_osi_cred); VOP_UNLOCK(tfile->vnode, 0, current_proc()); AFS_GLOCK(); #else +#if defined(AFS_FBSD_ENV) + AFS_GUNLOCK(); + VOP_LOCK(tfile->vnode, LK_EXCLUSIVE, curproc); + code = VOP_WRITE(tfile->vnode, &tuio, 0, &afs_osi_cred); + VOP_UNLOCK(tfile->vnode, 0, curproc); + AFS_GLOCK(); +#else code = VOP_RDWR(tfile->vnode, &tuio, UIO_WRITE, 0, &afs_osi_cred); -#endif /* AFS_DARWIN_ENV || AFS_FBSD_ENV */ +#endif /* AFS_FBSD_ENV */ +#endif /* AFS_DARWIN_ENV */ #endif /* AFS_LINUX20_ENV */ #endif /* AFS_HPUX100_ENV */ #endif /* AFS_OSF_ENV */ diff --git a/src/afs/afs.h b/src/afs/afs.h index 1660ea2..3b33e2a 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -598,11 +598,11 @@ struct vcache { * Do not try to get the vcache lock when the vlock is held */ afs_rwlock_t vlock; #endif /* defined(AFS_SUN5_ENV) */ -#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_DARWIN_ENV) #if defined(AFS_SUN5_ENV) krwlock_t rwlock; struct cred *credp; #endif +#if defined(AFS_SUN_ENV) || defined(AFS_ALPHA_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) afs_bozoLock_t pvnLock; /* see locks.x */ #endif #ifdef AFS_AIX32_ENV @@ -617,7 +617,10 @@ struct vcache { #ifdef AFS_DARWIN_ENV struct lock__bsd__ rwlock; #endif - afs_int32 parentVnode; /* Parent dir, if a file. */ +#ifdef AFS_FBSD_ENV + struct lock rwlock; +#endif + afs_int32 parentVnode; /* Parent dir, if a file. */ afs_int32 parentUnique; struct VenusFid *mvid; /* Either parent dir (if root) or root (if mt pt) */ char *linkData; /* Link data if a symlink. */ diff --git a/src/afs/afs_buffer.c b/src/afs/afs_buffer.c index 3fc6e4f..d11e84d 100644 --- a/src/afs/afs_buffer.c +++ b/src/afs/afs_buffer.c @@ -94,6 +94,9 @@ char *BufferData; #ifdef AFS_AIX_ENV extern struct buf *geteblk(); #endif +#ifdef AFS_FBSD_ENV +#define timecounter afs_timecounter +#endif /* The locks for individual buffer entries are now sometimes obtained while holding the * afs_bufferLock. Thus we now have a locking hierarchy: afs_bufferLock -> Buffers[].lock. */ diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index 65d0e02..4f59f94 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -61,9 +61,10 @@ simple_lock_data_t afs_global_lock; #elif defined(AFS_DARWIN_ENV) struct lock__bsd__ afs_global_lock; #elif defined(AFS_FBSD_ENV) -struct simplelock afs_global_lock; +struct lock afs_global_lock; +struct proc *afs_global_owner; #endif -#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) thread_t afs_global_owner; #endif /* AFS_OSF_ENV */ diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c index 2654e6f..1fd3620 100644 --- a/src/afs/afs_init.c +++ b/src/afs/afs_init.c @@ -102,7 +102,7 @@ extern afs_lock_t afs_ftf; /* Exported variables */ struct osi_dev cacheDev; /*Cache device*/ afs_int32 cacheInfoModTime; /*Last time cache info modified*/ -#if defined(AFS_OSF_ENV) || defined(AFS_DEC_ENV) || defined(AFS_DARWIN_ENV) +#if defined(AFS_OSF_ENV) || defined(AFS_DEC_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) struct mount *afs_cacheVfsp=0; #elif defined(AFS_LINUX20_ENV) struct super_block *afs_cacheSBp = 0; @@ -444,11 +444,15 @@ afs_InitCacheInfo(afile) TO_KERNEL_SPACE(); } #else -#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_DARWIN_ENV) if (!VFS_STATFS(filevp->v_mount, &st, current_proc())) #else +#if defined(AFS_FBSD_ENV) + if (!VFS_STATFS(filevp->v_mount, &st, curproc)) +#else if (!VFS_STATFS(filevp->v_vfsp, &st)) -#endif /* AFS_DARWIN_ENV || AFS_FBSD_ENV */ +#endif /* AFS_FBSD_ENV */ +#endif /* AFS_DARWIN_ENV */ #endif /* AFS_LINUX20_ENV */ #endif /* AIX41 */ #endif /* OSF */ diff --git a/src/afs/afs_mariner.c b/src/afs/afs_mariner.c index 23521d4..dd43304 100644 --- a/src/afs/afs_mariner.c +++ b/src/afs/afs_mariner.c @@ -81,7 +81,7 @@ void afs_MarinerLogFetch(avc, off, bytes, idx) taddr.sin_family = AF_INET; taddr.sin_addr.s_addr = afs_marinerHost; taddr.sin_port = htons(2106); -#ifdef AFS_OSF_ENV +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN taddr.sin_len = sizeof(taddr); #endif /* AFS_OSF_ENV */ tp = tp1 = (char *) osi_AllocSmallSpace(AFS_SMALLOCSIZ); @@ -114,6 +114,9 @@ void afs_MarinerLog(astring, avc) taddr.sin_family = AF_INET; taddr.sin_addr.s_addr = afs_marinerHost; taddr.sin_port = htons(2106); +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + taddr.sin_len = sizeof(taddr); +#endif /* AFS_OSF_ENV */ tp = buf = (char *) osi_AllocSmallSpace(AFS_SMALLOCSIZ); strcpy(tp, astring); diff --git a/src/afs/afs_osi.c b/src/afs/afs_osi.c index ac3f65d..7e81433 100644 --- a/src/afs/afs_osi.c +++ b/src/afs/afs_osi.c @@ -56,7 +56,7 @@ void osi_Init() afs_global_owner = (thread_t)0; #elif defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) lockinit(&afs_global_lock, PLOCK, "afs global lock", 0, 0); - afs_global_owner = (thread_t)0; + afs_global_owner = 0; #elif defined(AFS_AIX41_ENV) lock_alloc((void*)&afs_global_lock, LOCK_ALLOC_PIN, 1, 1); simple_lock_init((void *)&afs_global_lock); @@ -315,10 +315,13 @@ void afs_osi_Invisible() { #if AFS_HPUX101_ENV set_system_proc(u.u_procp); #endif -#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_DARWIN_ENV) /* maybe call init_process instead? */ current_proc()->p_flag |= P_SYSTEM; #endif +#if defined(AFS_FBSD_ENV) + curproc->p_flag |= P_SYSTEM; +#endif #if defined(AFS_SGI_ENV) vrelvm(); #endif /* AFS_SGI_ENV */ @@ -368,7 +371,27 @@ afs_osi_SetTime(atv) stime(&sta); AFS_GLOCK(); #else -#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_FBSD_ENV) + /* does not impliment security features of kern_time.c:settime() */ + struct timespec ts; + struct timeval tv,delta; + extern void (*lease_updatetime)(); + int s; + AFS_GUNLOCK(); + s=splclock(); + microtime(&tv); + delta=*atv; + timevalsub(&delta, &tv); + ts.tv_sec=atv->tv_sec; + ts.tv_nsec=atv->tv_usec * 1000; + set_timecounter(&ts); + (void) splsoftclock(); + lease_updatetime(delta.tv_sec); + splx(s); + resettodr(); + AFS_GLOCK(); +#else +#if defined(AFS_DARWIN_ENV) AFS_GUNLOCK(); setthetime(atv); AFS_GLOCK(); @@ -396,7 +419,8 @@ afs_osi_SetTime(atv) #ifdef AFS_AUX_ENV logtchg(atv->tv_sec); #endif -#endif /* AFS_DARWIN_ENV || AFS_FBSD_ENV */ +#endif /* AFS_DARWIN_ENV */ +#endif /* AFS_FBSD_ENV */ #endif /* AFS_SGI_ENV */ #endif /* AFS_SUN55_ENV */ #endif /* AFS_SUN5_ENV */ diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index d069c50..4871963 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -430,17 +430,28 @@ afs_xioctl () #endif /* AFS_SUN5_ENV */ #endif #ifndef AFS_LINUX22_ENV -#if defined(AFS_AIX32_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_AIX32_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) struct file *fd; #else register struct file *fd; #endif #endif +#if defined(AFS_FBSD_ENV) + register struct filedesc *fdp; +#endif register struct vcache *tvc; register int ioctlDone = 0, code = 0; AFS_STATCNT(afs_xioctl); -#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_FBSD_ENV) + fdp=p->p_fd; + if ((u_int)uap->fd >= fdp->fd_nfiles || + (fd = fdp->fd_ofiles[uap->fd]) == NULL) + return EBADF; + if ((fd->f_flag & (FREAD | FWRITE)) == 0) + return EBADF; +#else +#if defined(AFS_DARWIN_ENV) if ((code=fdgetf(p, uap->fd, &fd))) return code; #else @@ -481,7 +492,7 @@ afs_xioctl () #endif #endif #endif - +#endif /* first determine whether this is any sort of vnode */ #ifdef AFS_LINUX22_ENV tvc = (struct vcache *)ip; @@ -589,7 +600,10 @@ afs_xioctl () #endif code = ioctl(uap, rvp); #else -#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_FBSD_ENV) + return ioctl(p, uap); +#else +#if defined(AFS_DARWIN_ENV) return ioctl(p, uap, retval); #else #ifdef AFS_OSF_ENV @@ -609,6 +623,7 @@ afs_xioctl () #endif #endif #endif +#endif } #ifdef AFS_SUN5_ENV if (ioctlDone) @@ -1172,11 +1187,12 @@ static PStoreBehind(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) else code = EPERM; } - if (avc && (sbr->sb_thisfile != -1)) + if (avc && (sbr->sb_thisfile != -1)) { if (afs_AccessOK(avc, PRSFS_WRITE | PRSFS_ADMINISTER, areq, DONT_CHECK_MODE_BITS)) avc->asynchrony = sbr->sb_thisfile; else code = EACCES; + } *aoutSize = sizeof(struct sbstruct); sbr = (struct sbstruct *)aout; @@ -1437,7 +1453,11 @@ static PGCPAGs(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) if (set_parent_pag) { int pag; #if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_DARWIN_ENV) struct proc *p=current_proc(); /* XXX */ +#else + struct proc *p=curproc; /* XXX */ +#endif uprintf("Process %d (%s) tried to change pags in PSetTokens\n", p->p_pid, p->p_comm); if (!setpag(p, acred, -1, &pag, 1)) { diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index d8e08fc..5730e37 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -70,7 +70,7 @@ extern struct vcache *afs_globalVp; #ifdef AFS_OSF_ENV extern struct mount *afs_globalVFS; extern struct vnodeops Afs_vnodeops; -#elif defined(AFS_DARWIN_ENV) +#elif defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) extern struct mount *afs_globalVFS; #else extern struct vfs *afs_globalVFS; @@ -882,6 +882,19 @@ struct vcache *afs_NewVCache(struct VenusFid *afid, struct server *serverp, tvc->v.v_freelist.tqe_prev=(struct vnode **)0xdeadb; /*tvc->vrefCount++;*/ #endif +#ifdef AFS_FBSD_ENV + lockinit(&tvc->rwlock, PINOD, "vcache rwlock", 0, 0); + cache_purge((struct vnode *)tvc); + tvc->v.v_data=tvc; + tvc->v.v_tag=VT_AFS; +#ifndef VSTANDARD + tvc->v.v_usecount++; /* steal an extra ref for now so vfree never happens */ + /* this will prevent the vfs layer from reusing + * afs vnodes, but afs will eventually run out of + * vcache's and panic... + */ +#endif +#endif /* * The proper value for mvstat (for root fids) is setup by the caller. */ diff --git a/src/afs/lock.h b/src/afs/lock.h index 774b237..8a6266b 100644 --- a/src/afs/lock.h +++ b/src/afs/lock.h @@ -106,10 +106,14 @@ extern tid_t thread_self(); #ifdef AFS_LINUX20_ENV #define MyPidxx current->pid #else -#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_DARWIN_ENV) #define MyPidxx (current_proc()->p_pid ) #else +#if defined(AFS_FBSD_ENV) +#define MyPidxx (curproc->p_pid ) +#else #define MyPidxx (u.u_procp->p_pid ) +#endif /* AFS_FBSD_ENV */ #endif /* AFS_DARWIN_ENV */ #endif /* AFS_LINUX20_ENV */ #endif /* AFS_SGI64_ENV */ diff --git a/src/afs/sysincludes.h b/src/afs/sysincludes.h index 14c42fb..231c99e 100644 --- a/src/afs/sysincludes.h +++ b/src/afs/sysincludes.h @@ -74,7 +74,7 @@ struct xfs_inode_info {}; #include #else /* AFS_LINUX22_ENV */ -#if defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) +#if defined(AFS_DARWIN_ENV) #define _MACH_ETAP_H_ typedef unsigned short etap_event_t; #endif @@ -180,7 +180,7 @@ typedef unsigned short etap_event_t; #endif /* AFS_DEC_ENV */ -#ifndef AFS_SGI64_ENV +#if !defined(AFS_SGI64_ENV) && !defined(AFS_FBSD_ENV) #include "../h/user.h" #endif /* AFS_SGI64_ENV */ #define MACH_USER_API 1 @@ -223,17 +223,20 @@ struct vfspage; /* for vnode.h compiler warnings */ # include # include # include +# include #ifndef AFS_FBSD_ENV # include #define timeout_fcn_t mach_timeout_fcn_t # include #else +MALLOC_DECLARE(M_AFS); # include # include # include # include # include # include +# include #endif #undef timeout_fcn_t #define _DIR_H_ diff --git a/src/afsmonitor/afsmonitor.c b/src/afsmonitor/afsmonitor.c index 0c608ae..9d3e8a7 100644 --- a/src/afsmonitor/afsmonitor.c +++ b/src/afsmonitor/afsmonitor.c @@ -274,6 +274,7 @@ extern char *cm_categories[]; /* cache manager data category names */ +#ifndef AFS_XBSD_ENV /* strcasestr(): Return first occurence of pattern s2 in s1, case insensitive. @@ -305,7 +306,7 @@ char *s2; } return ((char *)NULL); } - +#endif struct hostent *GetHostByName(name) char *name; @@ -3491,6 +3492,9 @@ afsmon_execute() memcpy(&(curr_skt->sin_addr.s_addr), he->h_addr, 4); curr_skt->sin_family = htons(AF_INET); /*Internet family*/ curr_skt->sin_port = htons(7000); /*FileServer port*/ +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + curr_skt->sin_len = sizeof(struct sockaddr_in); +#endif /* get the next dude */ curr_skt++; @@ -3562,6 +3566,9 @@ afsmon_execute() memcpy(&(curr_skt->sin_addr.s_addr), he->h_addr, 4); curr_skt->sin_family = htons(AF_INET); /*Internet family*/ curr_skt->sin_port = htons(7001); /*Cache Manager port*/ +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + curr_skt->sin_len = sizeof(struct sockaddr_in); +#endif /* get the next dude */ curr_skt++; diff --git a/src/auth/cellconfig.c b/src/auth/cellconfig.c index f0d2d0a..a296d5f 100644 --- a/src/auth/cellconfig.c +++ b/src/auth/cellconfig.c @@ -539,6 +539,9 @@ static ParseHostLine(aline, addr, aname, aclone) if (code != 5) return AFSCONF_SYNTAX; addr->sin_family = AF_INET; addr->sin_port = 0; +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + addr->sin_len = sizeof(struct sockaddr_in); +#endif tp = (char *) &addr->sin_addr; *tp++ = c1; *tp++ = c2; diff --git a/src/bucoord/commands.c b/src/bucoord/commands.c index bf13cab..1b4e8a3 100644 --- a/src/bucoord/commands.c +++ b/src/bucoord/commands.c @@ -325,6 +325,9 @@ int EvalVolumeSet2(aconfig, avs, avols, uclient) tvd->server.sin_addr.s_addr = entries[e].serverNumber[ei]; tvd->server.sin_port = 0; /* default FS port */ tvd->server.sin_family = AF_INET; +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + tvd->server.sin_len = sizeof(struct sockaddr_in); +#endif /* String tvd off of partition struct */ tvd->next = ps->vdlist; diff --git a/src/bucoord/config.c b/src/bucoord/config.c index a2aafe2..2a3a72c 100644 --- a/src/bucoord/config.c +++ b/src/bucoord/config.c @@ -116,6 +116,9 @@ char *aname; { tentry->addr.sin_family = AF_INET; memcpy(&tentry->addr.sin_addr.s_addr, th->h_addr, sizeof(afs_int32)); tentry->addr.sin_port = 0; +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + tentry->addr.sin_len = sizeof(struct sockaddr_in); +#endif tentry->portOffset = aport; return 0; } diff --git a/src/bucoord/dsvs.c b/src/bucoord/dsvs.c index 9ed15be..97521d7 100644 --- a/src/bucoord/dsvs.c +++ b/src/bucoord/dsvs.c @@ -151,6 +151,9 @@ int bc_ParseHost(aname, asockaddr) /* * Four chunks were read, so we assume success. Construct the socket. */ +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + asockaddr->sin_len=sizeof(struct sockaddr_in); +#endif asockaddr->sin_family = AF_INET; asockaddr->sin_port = 0; addr = (b1<<24) | (b2<<16) | (b3<<8) | b4; @@ -180,6 +183,9 @@ int bc_ParseHost(aname, asockaddr) /* * We found a mapping; construct the socket. */ +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + asockaddr->sin_len=sizeof(struct sockaddr_in); +#endif asockaddr->sin_family = AF_INET; asockaddr->sin_port = 0; memcpy(&tmp1, th->h_addr, sizeof(afs_int32)); diff --git a/src/bucoord/tape_hosts.c b/src/bucoord/tape_hosts.c index 7a96a84..af13966 100644 --- a/src/bucoord/tape_hosts.c +++ b/src/bucoord/tape_hosts.c @@ -285,6 +285,9 @@ int bc_ParseHosts() the->portOffset = port; if (th) { memcpy(&the->addr.sin_addr.s_addr, th->h_addr, 4); +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + the->addr.sin_len = sizeof(struct sockaddr_in); +#endif the->addr.sin_family = AF_INET; the->addr.sin_port = 0; } diff --git a/src/butc/dump.c b/src/butc/dump.c index 37019d2..7c4448e 100644 --- a/src/butc/dump.c +++ b/src/butc/dump.c @@ -914,6 +914,9 @@ dumpPass(dparamsPtr, passNumber) server.sin_addr.s_addr = vldbEntry.serverNumber[e]; server.sin_port = 0; server.sin_family = AF_INET; +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + server.sin_len = sizeof(struct sockaddr_in); +#endif curDump->hostAddr = HOSTADDR(&server); curDump->partition = vldbEntry.serverPartition[e]; diff --git a/src/cf/osconf.m4 b/src/cf/osconf.m4 index f7158fc..bbe75a7 100644 --- a/src/cf/osconf.m4 +++ b/src/cf/osconf.m4 @@ -126,7 +126,47 @@ case $AFS_SYSNAME in TXLIBS="/usr/lib/libncurses.so" XCFLAGS="-O2 -pipe" XLIBS="${LIB_AFSDB} -lcompat" - YACC="bison -y" + YACC="byacc" + ;; + + i386_fbsd_43) + LEX="flex -l" + MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}' + MT_LIBS="-pthread" + PAM_CFLAGS="-O2 -pipe -fPIC" + SHLIB_LDFLAGS="-shared -Xlinker -x" + TXLIBS="/usr/lib/libncurses.so" + XCFLAGS="-O2 -pipe" + XLIBS="${LIB_AFSDB} -lcompat" + YACC="byacc" + ;; + + i386_fbsd_44) + LEX="flex -l" + MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}' + MT_LIBS="-pthread" + #MT_CFLAGS='-DAFS_PTHREAD_ENV -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads ${XCFLAGS}' + #MT_LIBS="-L/usr/local/lib -llthread -llgcc_r" + PAM_CFLAGS="-O2 -pipe -fPIC" + SHLIB_LDFLAGS="-shared -Xlinker -x" + TXLIBS="/usr/lib/libncurses.so" + XCFLAGS="-O2 -pipe" + XLIBS="${LIB_AFSDB} -lcompat" + YACC="byacc" + ;; + + i386_fbsd_45) + LEX="flex -l" + MT_CFLAGS='-DAFS_PTHREAD_ENV -pthread -D_REENTRANT ${XCFLAGS}' + MT_LIBS="-pthread" + #MT_CFLAGS='-DAFS_PTHREAD_ENV -D_THREAD_SAFE -I/usr/local/include/pthread/linuxthreads ${XCFLAGS}' + #MT_LIBS="-L/usr/local/lib -llthread -llgcc_r" + PAM_CFLAGS="-O2 -pipe -fPIC" + SHLIB_LDFLAGS="-shared -Xlinker -x" + TXLIBS="/usr/lib/libncurses.so" + XCFLAGS="-O2 -pipe" + XLIBS="${LIB_AFSDB} -lcompat" + YACC="byacc" ;; *nbsd15) diff --git a/src/config/afs_sysnames.h b/src/config/afs_sysnames.h index 0d89e40..e386b9a 100644 --- a/src/config/afs_sysnames.h +++ b/src/config/afs_sysnames.h @@ -141,6 +141,9 @@ #define SYS_NAME_ID_alpha_linux_24 2002 #define SYS_NAME_ID_i386_fbsd_42 2100 +#define SYS_NAME_ID_i386_fbsd_43 2101 +#define SYS_NAME_ID_i386_fbsd_44 2102 +#define SYS_NAME_ID_i386_fbsd_45 2103 #define SYS_NAME_ID_ia64_linux2 2200 #define SYS_NAME_ID_ia64_linux22 2201 diff --git a/src/config/param.i386_fbsd_42.h b/src/config/param.i386_fbsd_42.h index 15fd469..7e3a557 100644 --- a/src/config/param.i386_fbsd_42.h +++ b/src/config/param.i386_fbsd_42.h @@ -16,7 +16,6 @@ #define AFS_X86_FBSD42_ENV 1 #define AFS_X86_ENV 1 #define AFS_NONFSTRANS 1 -#define AFS_KERBEROS_ENV 1 #define O_SYNC O_FSYNC #define FTRUNC O_TRUNC @@ -54,6 +53,7 @@ #define AFS_HAVE_FFS 1 /* Use system's ffs. */ #define AFS_HAVE_STATVFS 0 /* System doesn't supports statvfs */ +#define RXK_LISTENER_ENV 1 #define AFS_GCPAGS 0 /* if nonzero, garbage collect PAGs */ #define AFS_USE_GETTIMEOFDAY 1 /* use gettimeofday to implement rx clock */ @@ -73,8 +73,8 @@ #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 AFS_KALLOC(x) malloc(x, M_AFS, M_WAITOK) +#define AFS_KFREE(x,y) free(x,M_AFS) #define v_count v_usecount #define v_vfsp v_mount #define vfs_bsize mnt_stat.f_bsize diff --git a/src/config/param.i386_fbsd_42_usr.h b/src/config/param.i386_fbsd_42_usr.h index 1d8e79c..b9abf7d 100644 --- a/src/config/param.i386_fbsd_42_usr.h +++ b/src/config/param.i386_fbsd_42_usr.h @@ -9,7 +9,6 @@ #define AFS_USR_FBSD42_ENV 1 #define AFS_USR_FBSD_ENV 1 #define AFS_NONFSTRANS 1 -#define AFS_KERBEROS_ENV #define O_SYNC O_FSYNC diff --git a/src/config/param.i386_fbsd_43.h b/src/config/param.i386_fbsd_43.h new file mode 100644 index 0000000..7a2d347 --- /dev/null +++ b/src/config/param.i386_fbsd_43.h @@ -0,0 +1,117 @@ +#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_FBSD_ENV 1 +#define AFS_FBSD40_ENV 1 +#define AFS_FBSD42_ENV 1 +#define AFS_FBSD43_ENV 1 +#define AFS_X86_FBSD_ENV 1 +#define AFS_X86_FBSD40_ENV 1 +#define AFS_X86_FBSD42_ENV 1 +#define AFS_X86_FBSD43_ENV 1 +#define AFS_X86_ENV 1 +#define AFS_NONFSTRANS 1 +#define O_SYNC O_FSYNC +#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_43" +#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_43 + +#define AFS_HAVE_FFS 1 /* Use system's ffs. */ +#define AFS_HAVE_STATVFS 0 /* System doesn't supports statvfs */ + +#define RXK_LISTENER_ENV 1 +#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) malloc(x, M_AFS, M_WAITOK) +#define AFS_KFREE(x,y) free(x,M_AFS) +#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_fbsd_43_usr.h b/src/config/param.i386_fbsd_43_usr.h new file mode 100644 index 0000000..dc06748 --- /dev/null +++ b/src/config/param.i386_fbsd_43_usr.h @@ -0,0 +1,60 @@ +#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_FBSD43_ENV 1 +#define AFS_USR_FBSD_ENV 1 +#define AFS_NONFSTRANS 1 + +#define O_SYNC O_FSYNC + +#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_43" +#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_43 +#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/config/param.i386_fbsd_44.h b/src/config/param.i386_fbsd_44.h new file mode 100644 index 0000000..b7ac6fb --- /dev/null +++ b/src/config/param.i386_fbsd_44.h @@ -0,0 +1,119 @@ +#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_FBSD_ENV 1 +#define AFS_FBSD40_ENV 1 +#define AFS_FBSD42_ENV 1 +#define AFS_FBSD43_ENV 1 +#define AFS_FBSD44_ENV 1 +#define AFS_X86_FBSD_ENV 1 +#define AFS_X86_FBSD40_ENV 1 +#define AFS_X86_FBSD42_ENV 1 +#define AFS_X86_FBSD43_ENV 1 +#define AFS_X86_FBSD44_ENV 1 +#define AFS_X86_ENV 1 +#define AFS_NONFSTRANS 1 +#define O_SYNC O_FSYNC +#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_44" +#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_44 + +#define AFS_HAVE_FFS 1 /* Use system's ffs. */ +#define AFS_HAVE_STATVFS 0 /* System doesn't supports statvfs */ + +#define RXK_LISTENER_ENV 1 +#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) malloc(x, M_AFS, M_WAITOK) +#define AFS_KFREE(x,y) free(x,M_AFS) +#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_fbsd_44_usr.h b/src/config/param.i386_fbsd_44_usr.h new file mode 100644 index 0000000..201a46c --- /dev/null +++ b/src/config/param.i386_fbsd_44_usr.h @@ -0,0 +1,61 @@ +#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_FBSD43_ENV 1 +#define AFS_USR_FBSD44_ENV 1 +#define AFS_USR_FBSD_ENV 1 +#define AFS_NONFSTRANS 1 + +#define O_SYNC O_FSYNC + +#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_44" +#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_44 +#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/config/param.i386_fbsd_45.h b/src/config/param.i386_fbsd_45.h new file mode 100644 index 0000000..6a80d6b --- /dev/null +++ b/src/config/param.i386_fbsd_45.h @@ -0,0 +1,120 @@ +#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_FBSD_ENV 1 +#define AFS_FBSD40_ENV 1 +#define AFS_FBSD42_ENV 1 +#define AFS_FBSD43_ENV 1 +#define AFS_FBSD44_ENV 1 +#define AFS_FBSD45_ENV 1 +#define AFS_X86_FBSD_ENV 1 +#define AFS_X86_FBSD40_ENV 1 +#define AFS_X86_FBSD42_ENV 1 +#define AFS_X86_FBSD43_ENV 1 +#define AFS_X86_FBSD45_ENV 1 +#define AFS_X86_ENV 1 +#define AFS_NONFSTRANS 1 +#define O_SYNC O_FSYNC +#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_44" +#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_44 + +#define AFS_HAVE_FFS 1 /* Use system's ffs. */ +#define AFS_HAVE_STATVFS 0 /* System doesn't supports statvfs */ + +#define RXK_LISTENER_ENV 1 +#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) malloc(x, M_AFS, M_WAITOK) +#define AFS_KFREE(x,y) free(x,M_AFS) +#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_fbsd_45_usr.h b/src/config/param.i386_fbsd_45_usr.h new file mode 100644 index 0000000..d1bcbae --- /dev/null +++ b/src/config/param.i386_fbsd_45_usr.h @@ -0,0 +1,62 @@ +#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_FBSD43_ENV 1 +#define AFS_USR_FBSD44_ENV 1 +#define AFS_USR_FBSD45_ENV 1 +#define AFS_USR_FBSD_ENV 1 +#define AFS_NONFSTRANS 1 + +#define O_SYNC O_FSYNC + +#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_45" +#define SYS_NAME_ID SYS_NAME_ID_i386_fbsd_45 +#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/fsint/afsaux.c b/src/fsint/afsaux.c index 562efdf..32edb08 100644 --- a/src/fsint/afsaux.c +++ b/src/fsint/afsaux.c @@ -22,7 +22,7 @@ RCSID("$Header$"); #include "../afs/afsincludes.h" #include "../rx/xdr.h" #else /* defined(UKERNEL) */ -#if defined(AFS_ALPHA_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) +#if defined(AFS_ALPHA_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) #include "../afs/sysincludes.h" #include "../afs/afsincludes.h" #else @@ -68,7 +68,7 @@ static afs_int32 bslosers = 0; #endif #if (defined(AFS_AIX_ENV) && !defined(AUTH_DES)) || (!defined(AFS_SUN_ENV)) && !defined(AFS_SGI_ENV) && !defined(AFS_ALPHA_ENV) && !defined(AFS_SUN5_ENV) #ifndef AFS_AIX32_ENV -#if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) +#if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_FBSD_ENV) /* * XDR chars; from user mode xdr package. */ diff --git a/src/kauth/authclient.c b/src/kauth/authclient.c index 82d7ecd..7851710 100644 --- a/src/kauth/authclient.c +++ b/src/kauth/authclient.c @@ -91,6 +91,10 @@ void ka_ExplicitCell ( explicit_cell_server_list.hostName[i][0] = 0; explicit_cell_server_list.hostAddr[i].sin_port = htons(AFSCONF_KAUTHPORT); +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + explicit_cell_server_list.hostAddr[i].sin_len = + sizeof(struct sockaddr_in); +#endif explicit = 1; } else break; diff --git a/src/kauth/krb_udp.c b/src/kauth/krb_udp.c index 79dbf77..4f5d9ca 100644 --- a/src/kauth/krb_udp.c +++ b/src/kauth/krb_udp.c @@ -841,6 +841,9 @@ afs_int32 init_krb_udp () krb4name = "kerberos4"; sp = getservbyname(krb4name, "udp"); taddr.sin_family = AF_INET; /* added for NCR port */ +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + taddr.sin_len = sizeof(struct sockaddr_in); +#endif if ( !sp ) { /* if kerberos-4 is not available, try "kerberos-iv" */ diff --git a/src/libafs/MakefileProto.FBSD.in b/src/libafs/MakefileProto.FBSD.in index 1d35739..6944a4c 100644 --- a/src/libafs/MakefileProto.FBSD.in +++ b/src/libafs/MakefileProto.FBSD.in @@ -13,6 +13,9 @@ AFS_OS_OBJS = \ osi_sleep.o \ osi_vm.o \ osi_vnodeops.o \ + osi_module.o \ + xdr.o \ + xdr_array.o \ xdr_int64.o AFS_OS_NFSOBJS = \ @@ -28,7 +31,7 @@ AFS_OS_NONFSOBJS = \ # -DSWAPTYPE=1 -DUERF -DOSF -DCOMPAT_43 -DUFS \ # -DRT -DKERNEL -D_KERNEL KDEFS=-Wall -fformat-extensions -ansi -nostdinc -I/usr/include -D_KERNEL \ - -elf -mpreferred-stack-boundary=2 -I/usr/src/sys/sys -I../afs + -DKLD_MODULE -elf -mpreferred-stack-boundary=2 -I.. -I../afs DBUG = -O2 DEFINES= -DAFSDEBUG -DKERNEL -DAFS -DVICE -DNFS -DUFS -DINET -DQUOTA -DGETMOUNT OPTF=${OPT} @@ -77,19 +80,19 @@ DEST_LIBAFSNONFS = ${DEST}/root.client/bin/${LIBAFSNONFS} # libafs: $(LIBAFS) $(LIBAFSNONFS) -# libafs: $(LIBAFSNONFS) +libafs: $(LIBAFSNONFS) # install_libafs: $(INST_LIBAFS) $(INST_LIBAFSNONFS) -# install_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} +dest_libafs: $(DEST_LIBAFSNONFS) +#libafs: +# echo WARNING: No kernel module for ${SYS_NAME} -install_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} +#dest_libafs: +# echo WARNING: No kernel module for ${SYS_NAME} $(INST_LIBAFS): $(LIBAFS) @@ -105,10 +108,16 @@ $(DEST_LIBAFSNONFS): $(LIBAFSNONFS) $(INSTALL) -f $? $@ ${LIBAFS}: $(AFSAOBJS) $(AFSNFSOBJS) - $(LD) -r -o ${LIBAFS} ${AFSAOBJS} ${AFSNFSOBJS} + $(LD) -r -o ${LIBAFS}.kld ${AFSAOBJS} ${AFSNFSOBJS} + gensetdefs ${LIBAFS}.kld + $(MAKE) setdef0.o setdef1.o + $(LD) -Bshareable -o ${LIBAFS} setdef0.o ${LIBAFS}.kld setdef1.o ${LIBAFSNONFS}: $(AFSAOBJS) $(AFSNONFSOBJS) - $(LD) -r -o ${LIBAFSNONFS} ${AFSAOBJS} ${AFSNONFSOBJS} + $(LD) -r -o ${LIBAFSNONFS}.kld ${AFSAOBJS} ${AFSNONFSOBJS} + gensetdefs ${LIBAFSNONFS}.kld + $(MAKE) setdef0.o setdef1.o + $(LD) -Bshareable -o ${LIBAFSNONFS} setdef0.o ${LIBAFSNONFS}.kld setdef1.o # Object build rules: @@ -130,5 +139,15 @@ osi_vm.o: $(AFS)/osi_vm.c $(CRULE1) osi_vnodeops.o: $(AFS)/osi_vnodeops.c $(CRULE1) +osi_module.o: $(AFS)/osi_module.c + $(CRULE1) +xdr.o: $(RX)/xdr.c + $(CRULE1) +xdr_array.o: $(RX)/xdr_array.c + $(CRULE1) xdr_int64.o: $(RX)/xdr_int64.c $(CRULE1) +setdef0.o: setdef0.c + $(CRULE1) +setdef1.o: setdef1.c + $(CRULE1) diff --git a/src/libuafs/MakefileProto.FBSD.in b/src/libuafs/MakefileProto.FBSD.in index 5551baf..06ead0e 100644 --- a/src/libuafs/MakefileProto.FBSD.in +++ b/src/libuafs/MakefileProto.FBSD.in @@ -55,7 +55,7 @@ UAFS/$(LIBUAFS): setup_uafs $(MAKE) $(LIBUAFS) DESTDIR=${DESTDIR} AFSWEB/$(LIBAFSWEB): setup_nsafs -cd AFSWEB; \ + cd AFSWEB; \ $(MAKE) $(LIBAFSWEB) DESTDIR=${DESTDIR} AFSWEB/$(LIBAFSWEBKRB): setup_nsafs diff --git a/src/ptserver/testpt.c b/src/ptserver/testpt.c index ad94f8f..9fab0c3 100644 --- a/src/ptserver/testpt.c +++ b/src/ptserver/testpt.c @@ -917,6 +917,9 @@ static int MyBeforeProc (as, arock) memcpy(&cellinfo.hostAddr[i].sin_addr, th->h_addr, sizeof(afs_int32)); cellinfo.hostAddr[i].sin_family = AF_INET; cellinfo.hostAddr[i].sin_port = 0; +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + cellinfo.hostAddr[i].sin_len = sizeof(struct sockaddr_in); +#endif } cellinfo.numServers = i; strcpy (cellinfo.name, lcell); diff --git a/src/rx/FBSD/rx_kmutex.h b/src/rx/FBSD/rx_kmutex.h index 771d2fc..acf9b98 100644 --- a/src/rx/FBSD/rx_kmutex.h +++ b/src/rx/FBSD/rx_kmutex.h @@ -1,20 +1,26 @@ -/* Copyright Transarc Corporation 1998 - All Rights Reserved - * +/* + * 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. * - * DUX implementation. + * FBSD implementation. */ #ifndef _RX_KMUTEX_H_ #define _RX_KMUTEX_H_ -#ifdef AFS_FBSD40_ENV - +#include +#include #include -/* #include */ -/* #include */ -#define RX_ENABLE_LOCKS 1 +#define RX_ENABLE_LOCKS 1 #define AFS_GLOBAL_RXLOCK_KERNEL /* @@ -27,71 +33,133 @@ #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((vm_offset_t)(cv), 0); \ - MUTEX_EXIT(lck); \ - thread_block(); \ - if (isGlockOwner) AFS_GLOCK(); \ - MUTEX_ENTER(lck); \ - } - -#define CV_TIMEDWAIT(cv,lck,t) { \ - int isGlockOwner = ISAFS_GLOCK(); \ - if (isGlockOwner) AFS_GUNLOCK(); \ - assert_wait((vm_offset_t)(cv), 0); \ - thread_set_timeout(t); \ - MUTEX_EXIT(lck); \ - thread_block(); \ - if (isGlockOwner) AFS_GLOCK(); \ - MUTEX_ENTER(lck); \ - } - -#define CV_SIGNAL(cv) thread_wakeup_one((vm_offset_t)(cv)) -#define CV_BROADCAST(cv) thread_wakeup((vm_offset_t)(cv)) + int isGlockOwner = ISAFS_GLOCK(); \ + if (isGlockOwner) AFS_GUNLOCK(); \ + MUTEX_EXIT(lck); \ + tsleep(cv, PSOCK, "afs_rx_cv_wait", 0); \ + if (isGlockOwner) AFS_GLOCK(); \ + MUTEX_ENTER(lck); \ + } + +#define CV_TIMEDWAIT(cv,lck,t) { \ + int isGlockOwner = ISAFS_GLOCK(); \ + if (isGlockOwner) AFS_GUNLOCK(); \ + MUTEX_EXIT(lck); \ + tsleep(cv, PSOCK, "afs_rx_cv_timedwait", t); \ + if (isGlockOwner) AFS_GLOCK(); \ + MUTEX_ENTER(lck); \ + +#define CV_SIGNAL(cv) wakeup_one(cv) +#define CV_BROADCAST(cv) wakeup(cv) + +#define osi_rxWakeup(cv) wakeup(cv) +typedef int afs_kcondvar_t; +#define HEAVY_LOCKS +#ifdef NULL_LOCKS typedef struct { - struct simplelock lock; + struct proc *owner; } afs_kmutex_t; -typedef int afs_kcondvar_t; -#define osi_rxWakeup(cv) thread_wakeup((vm_offset_t)(cv)) +#define MUTEX_INIT(a,b,c,d) \ + do { \ + (a)->owner = 0; \ + } while(0); +#define MUTEX_DESTROY(a) \ + do { \ + (a)->owner = (struct proc *)-1; \ + } while(0); +#define MUTEX_ENTER(a) \ + do { \ + osi_Assert((a)->owner == 0); \ + (a)->owner = curproc; \ + } while(0); +#define MUTEX_TRYENTER(a) \ + ( osi_Assert((a)->owner == 0), (a)->owner = curproc, 1) +#define MUTEX_EXIT(a) \ + do { \ + osi_Assert((a)->owner == curproc); \ + (a)->owner = 0; \ + } while(0); -#define LOCK_INIT(a,b) \ +#undef MUTEX_ISMINE +#define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == curproc) + +#else +#ifdef HEAVY_LOCKS +typedef struct { + struct lock lock; + struct proc *owner; +} afs_kmutex_t; + + +#define MUTEX_INIT(a,b,c,d) \ + do { \ + lockinit(&(a)->lock,PSOCK, "afs rx mutex", 0, 0); \ + (a)->owner = 0; \ + } while(0); +#define MUTEX_DESTROY(a) \ + do { \ + (a)->owner = (struct proc *)-1; \ + } while(0); +#define MUTEX_ENTER(a) \ + do { \ + lockmgr(&(a)->lock, LK_EXCLUSIVE, 0, curproc); \ + osi_Assert((a)->owner == 0); \ + (a)->owner = curproc; \ + } while(0); +#define MUTEX_TRYENTER(a) \ + ( lockmgr(&(a)->lock, LK_EXCLUSIVE|LK_NOWAIT, 0, curproc) ? 0 : ((a)->owner = curproc, 1) ) +#define xMUTEX_TRYENTER(a) \ + ( osi_Assert((a)->owner == 0), (a)->owner = curproc, 1) +#define MUTEX_EXIT(a) \ do { \ - usimple_lock_init(&(a)->lock); \ + osi_Assert((a)->owner == curproc); \ + (a)->owner = 0; \ + lockmgr(&(a)->lock, LK_RELEASE, 0, curproc); \ } while(0); + +#undef MUTEX_ISMINE +#define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == curproc) +#else +typedef struct { + struct simplelock lock; + struct proc *owner; +} afs_kmutex_t; + + #define MUTEX_INIT(a,b,c,d) \ do { \ - usimple_lock_init(&(a)->lock); \ + simple_lock_init(&(a)->lock); \ + (a)->owner = 0; \ } while(0); #define MUTEX_DESTROY(a) \ do { \ - usimple_lock_terminate(&(a)->lock); \ + (a)->owner = (struct proc *)-1; \ } while(0); #define MUTEX_ENTER(a) \ do { \ - usimple_lock(&(a)->lock); \ + simple_lock(&(a)->lock); \ + osi_Assert((a)->owner == 0); \ + (a)->owner = curproc; \ } while(0); #define MUTEX_TRYENTER(a) \ - usimple_lock(&(a)->lock) + ( simple_lock_try(&(a)->lock) ? 0 : ((a)->owner = curproc, 1) ) #define MUTEX_EXIT(a) \ do { \ - usimple_unlock(&(a)->lock); \ + osi_Assert((a)->owner == curproc); \ + (a)->owner = 0; \ + simple_unlock(&(a)->lock); \ } while(0); #undef MUTEX_ISMINE -#define MUTEX_ISMINE(a) 1 -/* - #define MUTEX_ISMINE(a) - (((afs_kmutex_t *)(a))->owner == current_thread()) -*/ +#define MUTEX_ISMINE(a) (((afs_kmutex_t *)(a))->owner == curproc) +#endif +#endif + #undef osirx_AssertMine extern void osirx_AssertMine(afs_kmutex_t *lockaddr, char *msg); -#endif /* FBSD40 */ - - #endif /* _RX_KMUTEX_H_ */ diff --git a/src/rx/FBSD/rx_knet.c b/src/rx/FBSD/rx_knet.c index 43914fd..91dee14 100644 --- a/src/rx/FBSD/rx_knet.c +++ b/src/rx/FBSD/rx_knet.c @@ -29,6 +29,137 @@ RCSID("$Header$"); #include "../rx/rx_kcommon.h" +#ifdef RXK_LISTENER_ENV +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(); + } + code = soreceive(asocket, &sa, &u, NULL, NULL, NULL); +#if KNET_DEBUG + if (code) { + if (code == EINVAL) + Debugger("afs NetReceive busted"); + else + printf("y"); + } +#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", sa->sa_family); + } + } + return code; +} + +extern int rxk_ListenerPid; +void osi_StopListener(void) +{ + struct proc *p; + + soclose(rx_socket); + p=pfind(rxk_ListenerPid); + if (p) + psignal(p, SIGUSR1); +} + +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; + 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; + + addr->sin_len=sizeof(struct sockaddr_in); + + if (haveGlock) { + AFS_GUNLOCK(); + } +#if KNET_DEBUG + printf("+"); +#endif + code = sosend(asocket, addr, &u, NULL, NULL, 0, curproc); +#if KNET_DEBUG + if (code) { + if (code == EINVAL) + Debugger("afs NetSend busted"); + else + printf("z"); + } +#endif + if (haveGlock) { + AFS_GLOCK(); + } + return code; +} +#else +/* This code *almost* works :( */ static struct protosw parent_proto; /* udp proto switch */ static void rxk_input (struct mbuf *am, int iphlen); static void rxk_fasttimo (void); @@ -41,9 +172,11 @@ rxk_init() { last = inetdomain.dom_protoswNPROTOSW; for (tpro = inetdomain.dom_protosw; tpro < last; tpro++) if (tpro->pr_protocol == IPPROTO_UDP) { +#if 0 /* not exported */ /* force UDP checksumming on for AFS */ extern int udpcksum; udpcksum = 1; +#endif memcpy(&parent_proto, tpro, sizeof(parent_proto)); tpro->pr_input = rxk_input; tpro->pr_fasttimo = rxk_fasttimo; @@ -190,7 +323,6 @@ static void rxk_fasttimo (void) if (tproc = parent_proto.pr_fasttimo) (*tproc)(); } - /* 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 @@ -219,6 +351,8 @@ register struct sockbuf *sb; { return 0; } +/* We only have to do all the mbuf management ourselves if we can be called at + interrupt time. in RXK_LISTENER_ENV, we can just call sosend() */ int osi_NetSend(asocket, addr, dvec, nvec, asize, istack) register struct socket *asocket; @@ -239,15 +373,20 @@ osi_NetSend(asocket, addr, dvec, nvec, asize, istack) int i,tl,rlen; int mlen; int haveGlock; +#if KNET_DEBUG + static int before=0; +#endif AFS_STATCNT(osi_NetSend); - /* Actually, the Ultrix way is as good as any for us, so we don't bother with * special mbufs any more. Used to think we could get away with not copying * the data to the interface, but there's no way to tell the caller not to * reuse the buffers after sending, so we lost out on that trick anyway */ - s = splnet(); + if (trysblock(&asocket->so_snd)) { + splx(s); + return 1; + } mp = ⊤ i = 0; tdata = dvec[i].iov_base; @@ -257,6 +396,7 @@ osi_NetSend(asocket, addr, dvec, nvec, asize, istack) if (top == 0) { MGETHDR(m, M_DONTWAIT, MT_DATA); if (!m) { + sbunlock(&asocket->so_snd); splx(s); return 1; } @@ -268,6 +408,7 @@ osi_NetSend(asocket, addr, dvec, nvec, asize, istack) if (!m) { /* can't get an mbuf, give up */ if (top) m_freem(top); /* free mbuf list we're building */ + sbunlock(&asocket->so_snd); splx(s); return 1; } @@ -282,8 +423,6 @@ osi_NetSend(asocket, addr, dvec, nvec, asize, istack) * to ourself). */ if (asize >= 4 * MLEN) { /* try to get cluster mbuf */ - register struct mbuf *p; - /* different algorithms for getting cluster mbuf */ MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) @@ -334,32 +473,42 @@ nopages: um = m_get(M_DONTWAIT, MT_SONAME); if (!um) { if (top) m_freem(top); /* free mbuf chain */ - /* if this were vfs40, we'd do sbunlock(asocket, &asocket->so_snd), but - we don't do the locking at all for vfs40 systems */ + sbunlock(&asocket->so_snd); splx(s); return 1; } memcpy(mtod(um, caddr_t), addr, sizeof(*addr)); - um->m_len = sizeof(*addr); + addr->sin_len = um->m_len = sizeof(*addr); /* note that udp_usrreq frees funny mbuf. We hold onto data, but mbuf - * around it is gone. we free address ourselves. */ + * around it is gone. */ /* haveGlock = ISAFS_GLOCK(); if (haveGlock) { AFS_GUNLOCK(); } */ /* SOCKET_LOCK(asocket); */ /* code = (*asocket->so_proto->pr_usrreq)(asocket, PRU_SEND, tm, um, 0); */ +#if KNET_DEBUG + if (before) Debugger("afs NetSend before"); +#endif code = (*asocket->so_proto->pr_usrreqs->pru_send)(asocket, 0, tm, (struct sockaddr *) addr, - um, curproc); + um, &proc0); /* SOCKET_UNLOCK(asocket); */ /* if (haveGlock) { AFS_GLOCK(); } */ + sbunlock(&asocket->so_snd); splx(s); - m_free(um); - +#if KNET_DEBUG + if (code) { + if (code == EINVAL) + Debugger("afs NetSend busted"); + else + printf("z"); + } +#endif return code; } +#endif #endif /* AFS_FBSD40_ENV */ diff --git a/src/rx/rx.c b/src/rx/rx.c index cbec10e..166f38a 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -2409,7 +2409,7 @@ struct rx_packet *rxi_ReceivePacket(np, socket, host, port, tnop, newcallp) addr.sin_family = AF_INET; addr.sin_port = port; addr.sin_addr.s_addr = host; -#if defined(AFS_OSF_ENV) && defined(_KERNEL) +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN addr.sin_len = sizeof(addr); #endif /* AFS_OSF_ENV */ drop = (*rx_justReceived) (np, &addr); @@ -6165,6 +6165,9 @@ static int MakeDebugCall( taddr.sin_family = AF_INET; taddr.sin_port = remotePort; taddr.sin_addr.s_addr = remoteAddr; +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + taddr.sin_len = sizeof(struct sockaddr_in); +#endif while(1) { memset(&theader, 0, sizeof(theader)); theader.epoch = htonl(999); diff --git a/src/rx/rx_kcommon.c b/src/rx/rx_kcommon.c index b888d8f..da117bd 100644 --- a/src/rx/rx_kcommon.c +++ b/src/rx/rx_kcommon.c @@ -766,6 +766,9 @@ struct osi_socket *rxk_NewSocket(short aport) myaddr.sin_family = AF_INET; myaddr.sin_port = aport; myaddr.sin_addr.s_addr = 0; +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + myaddr.sin_len = sizeof(myaddr); +#endif #ifdef AFS_HPUX110_ENV bindnam = allocb_wait((addrsize+SO_MSGOFFSET+1), BPRI_MED); @@ -792,7 +795,6 @@ struct osi_socket *rxk_NewSocket(short aport) osi_Panic("osi_NewSocket: last attempt to reserve 32K failed!\n"); } #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) - myaddr.sin_len = sizeof(myaddr); #if defined(AFS_XBSD_ENV) code = sobind(newSocket, (struct sockaddr *)&myaddr, curproc); #else @@ -1025,7 +1027,10 @@ void rxk_Listener(void) #ifdef AFS_SUN5_ENV rxk_ListenerPid = curproc->p_pid; #endif /* AFS_SUN5_ENV */ -#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) +#ifdef AFS_FBSD_ENV + rxk_ListenerPid = curproc->p_pid; +#endif /* AFS_SUN5_ENV */ +#if defined(AFS_DARWIN_ENV) rxk_ListenerPid = current_proc()->p_pid; #endif #if defined(RX_ENABLE_LOCKS) && !defined(AFS_SUN5_ENV) diff --git a/src/rx/rx_kcommon.h b/src/rx/rx_kcommon.h index 92b2bc3..3d3ed69 100644 --- a/src/rx/rx_kcommon.h +++ b/src/rx/rx_kcommon.h @@ -53,6 +53,9 @@ typedef unsigned short etap_event_t; #ifdef AFS_SGI62_ENV #include "../h/hashing.h" #endif +#ifdef AFS_FBSD_ENV +#include "../h/sysctl.h" +#endif #include "../netinet/in.h" #include "../net/route.h" #include "../netinet/in_systm.h" diff --git a/src/rx/rx_packet.c b/src/rx/rx_packet.c index 8b7051e..12e2644 100644 --- a/src/rx/rx_packet.c +++ b/src/rx/rx_packet.c @@ -33,6 +33,12 @@ RCSID("$Header$"); #include "../afs/sysincludes.h" #endif #include "../h/socket.h" +#if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV) +#if !defined(AFS_OSF_ENV) && !defined(AFS_AIX41_ENV) +#include "../sys/mount.h" /* it gets pulled in by something later anyway */ +#endif +#include "../h/mbuf.h" +#endif #include "../netinet/in.h" #include "../afs/afs_osi.h" #include "../rx/rx_kmutex.h" @@ -42,12 +48,6 @@ RCSID("$Header$"); #include #endif #include "../rx/rx_packet.h" -#if !defined(AFS_SUN5_ENV) && !defined(AFS_LINUX20_ENV) -#if !defined(AFS_OSF_ENV) && !defined(AFS_AIX41_ENV) -#include "../sys/mount.h" /* it gets pulled in by something later anyway */ -#endif -#include "../h/mbuf.h" -#endif #endif /* defined(UKERNEL) */ #include "../rx/rx_globals.h" #else /* KERNEL */ @@ -1437,7 +1437,9 @@ static void rxi_SendDebugPacket(struct rx_packet *apacket, osi_socket asocket, taddr.sin_family = AF_INET; taddr.sin_port = aport; taddr.sin_addr.s_addr = ahost; - +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + taddr.sin_len = sizeof(struct sockaddr_in); +#endif /* We need to trim the niovecs. */ nbytes = apacket->length; diff --git a/src/rx/rx_user.c b/src/rx/rx_user.c index 0472a86..c761f31 100644 --- a/src/rx/rx_user.c +++ b/src/rx/rx_user.c @@ -120,6 +120,9 @@ osi_socket rxi_GetUDPSocket(u_short port) taddr.sin_addr.s_addr = 0; taddr.sin_family = AF_INET; taddr.sin_port = (u_short)port; +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + taddr.sin_len = sizeof(struct sockaddr_in); +#endif #define MAX_RX_BINDS 10 for (binds=0; binds +#include "afsutil.h" #ifdef AFS_NT40_ENV void afs_NTAbort(void) @@ -33,8 +34,7 @@ void AssertionFailed(char *file, int line) time_t when; time(&when); - strcpy(tdate, ctime(&when)); - tdate[24] = '0'; + afs_ctime(&when, tdate, 25); fprintf(stderr, "%s: Assertion failed! file %s, line %d.\n", tdate, file, line); fflush(stderr); diff --git a/src/viced/fsprobe.c b/src/viced/fsprobe.c index 5e81439..33f7738 100644 --- a/src/viced/fsprobe.c +++ b/src/viced/fsprobe.c @@ -101,6 +101,9 @@ main(argc, argv) memset((char *)&host, 0, sizeof(struct sockaddr_in)); host.sin_family = AF_INET; host.sin_addr.s_addr = inet_addr(av[0]); +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + host.sin_len = sizeof(struct sockaddr_in); +#endif if (host.sin_addr.s_addr != -1) { strcpy(hnamebuf, av[0]); hostname = hnamebuf; diff --git a/src/vol/fssync.c b/src/vol/fssync.c index a17d60f..a4756e3 100644 --- a/src/vol/fssync.c +++ b/src/vol/fssync.c @@ -236,9 +236,13 @@ static int getport(addr) memset(addr, 0, sizeof(*addr)); assert((sd = socket(AF_INET, SOCK_STREAM, 0)) >= 0); +#ifdef STRUCT_SOCKADDR_HAS_SA_LEN + addr->sin_len = sizeof(struct sockaddr_in); +#endif addr->sin_addr.s_addr = htonl(0x7f000001); addr->sin_family = AF_INET; /* was localhost->h_addrtype */ addr->sin_port = htons(2040); /* XXXX htons not _really_ neccessary */ + return sd; }