Re: Making more progress....

Kenny Freeman <[email protected]>
Newsgroups gmane.comp.file-systems.openafs.freebsd
Organization PCHG Internet Solutions
Message-ID <[email protected]>
I take it that this requires a current system. Seems to me that your patch 
doesn't work on a 5.1-RELEASE p10 system. I get an error about src/config/
afsconfig.h not existing near the end of the ./configure run. I don't have 
ssh access to that box yet so I can't post the configure output :/

-Kenny

On October 8, 2003 01:40 am, Garrett Wollman wrote:
> Updated patch available at
> <http://lcs.mit.edu/~wollman/openafs-fbsd52.patch>.  Changes in this
> version:
>
> - Doesn't crash when doing heavy recycling (e.g., listing
> /afs/sipb.mit.edu/users with a small cache).
>
> - I've rebroken shutdown (will investigate when I am sufficiently
> awake again).
>
> - Redundant vop_lock family routines eliminated (the standard ones are
> just fine for our purposes).
>
> - Includes correct fix for vop_symlink.
>
> - Includes preliminary autoconf glue to test for POSIX regex(3),
> eliminating need for libcompat.  (Same change should be made for
> OpenBSD.)  Jim Rees, feel free to commit these parts.
>
> -GAWollman
>
> (Patch included below for ease of review/commentary....)
>
> Index: acinclude.m4
> ===================================================================
> RCS file: /cvs/openafs/acinclude.m4,v
> retrieving revision 1.90
> diff -u -r1.90 acinclude.m4
> --- acinclude.m4	25 Sep 2003 16:26:10 -0000	1.90
> +++ acinclude.m4	8 Oct 2003 05:09:20 -0000
> @@ -806,7 +806,7 @@
>  AC_CHECK_HEADERS(mntent.h sys/vfs.h sys/param.h sys/fs_types.h
> sys/fstyp.h) AC_CHECK_HEADERS(sys/mount.h strings.h termios.h signal.h)
>  AC_CHECK_HEADERS(windows.h malloc.h winsock2.h direct.h io.h)
> -AC_CHECK_HEADERS(security/pam_modules.h siad.h usersec.h ucontext.h)
> +AC_CHECK_HEADERS(security/pam_modules.h siad.h usersec.h ucontext.h
> regex.h)
>
>  if test "$ac_cv_header_security_pam_modules_h" = "yes"; then
>  	HAVE_PAM="yes"
> @@ -817,6 +817,19 @@
>
>  AC_CHECK_FUNCS(utimes random srandom getdtablesize snprintf strlcat
> strlcpy re_comp re_exec) AC_CHECK_FUNCS(setprogname getprogname sigaction
> mkstemp vsnprintf strerror) +
> +AC_CHECK_FUNCS(regcomp regexec regerror)
> +AC_MSG_CHECKING([if you have the complete POSIX regex library])
> +if test "$ac_cv_header_regex_h" = "yes" && \
> +	test "$ac_cv_func_regcomp" = "yes" && \
> +	test "$ac_cv_func_regexec" = "yes" && \
> +	test "$ac_cv_func_regerror" = "yes"; then
> +    AC_DEFINE(HAVE_POSIX_REGEX)
> +    AC_MSG_RESULT(yes)
> +else
> +    AC_MSG_RESULT(no)
> +fi
> +
>  AC_CHECK_TYPE(ssize_t, int)
>  AC_SIZEOF_TYPE(long)
>
> Index: src/afs/afs.h
> ===================================================================
> RCS file: /cvs/openafs/src/afs/afs.h,v
> retrieving revision 1.42
> diff -u -r1.42 afs.h
> --- src/afs/afs.h	29 Aug 2003 22:00:04 -0000	1.42
> +++ src/afs/afs.h	8 Oct 2003 05:09:34 -0000
> @@ -545,15 +545,11 @@
>  #define VPageCleaning 0x2	/* Solaris - Cache Trunc Daemon sez keep out */
>
>  #define	CPSIZE	    2
> -#if defined(AFS_FBSD_ENV)
> -#define vrefCount   v.v_usecount
> -#else
> -#if defined(AFS_OBSD_ENV)
> +#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
>  #define vrefCount   v->v_usecount
>  #else
>  #define vrefCount   v.v_count
> -#endif /* AFS_OBSD_ENV */
> -#endif /* AFS_FBSD_ENV */
> +#endif /* AFS_[OF]BSD_ENV */
>
>  #ifdef AFS_LINUX24_ENV
>  #define VREFCOUNT(v)		atomic_read(&((vnode_t *) v)->v_count)
> @@ -598,7 +594,7 @@
>  extern afs_uint32 afs_stampValue;	/* stamp for pair's usage */
>  #define	MakeStamp()	(++afs_stampValue)
>
> -#if defined(AFS_OBSD_ENV)
> +#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
>  #define VTOAFS(v) ((struct vcache *)(v)->v_data)
>  #define AFSTOV(vc) ((vc)->v)
>  #else
> @@ -616,7 +612,7 @@
>   * !(avc->nextfree) && !avc->vlruq.next => (FreeVCList == avc->nextfree)
>   */
>  struct vcache {
> -#if defined(AFS_OBSD_ENV)
> +#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
>      struct vnode *v;
>  #else
>      struct vnode v;		/* Has reference count in v.v_count */
> Index: src/afs/afs_call.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/afs_call.c,v
> retrieving revision 1.62
> diff -u -r1.62 afs_call.c
> --- src/afs/afs_call.c	8 Aug 2003 21:54:34 -0000	1.62
> +++ src/afs/afs_call.c	8 Oct 2003 05:09:36 -0000
> @@ -64,13 +64,12 @@
>  struct lock__bsd__ afs_global_lock;
>  #endif
>
> -#if defined(AFS_XBSD_ENV)
> +#if defined(AFS_XBSD_ENV) && !defined(AFS_FBSD50_ENV)
>  struct lock afs_global_lock;
> -#ifdef AFS_FBSD50_ENV
> -struct thread *afs_global_owner;
> -#else
>  struct proc *afs_global_owner;
>  #endif
> +#ifdef AFS_FBSD50_ENV
> +struct mtx afs_global_mtx;
>  #endif
>
>  #if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV)
> Index: src/afs/afs_init.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/afs_init.c,v
> retrieving revision 1.26
> diff -u -r1.26 afs_init.c
> --- src/afs/afs_init.c	15 Jul 2003 23:14:12 -0000	1.26
> +++ src/afs/afs_init.c	8 Oct 2003 05:09:37 -0000
> @@ -41,7 +41,7 @@
>  int afs_sysnamecount = 0;
>  struct volume *Initialafs_freeVolList;
>  int afs_memvolumes = 0;
> -#ifdef AFS_OBSD_ENV
> +#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
>  static struct vnode *volumeVnode;
>  #endif
>
> @@ -295,7 +295,7 @@
>      struct osi_file *tfile;
>
>      AFS_STATCNT(afs_InitVolumeInfo);
> -#if defined(AFS_OBSD_ENV)
> +#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
>      /*
>       * On Open/NetBSD, we can get into big trouble if we don't hold the
> volume file * vnode.  SetupVolume holds afs_xvolume lock exclusive.
> @@ -428,19 +428,24 @@
>      cacheInode = filevp->i_ino;
>      afs_cacheSBp = filevp->i_sb;
>  #else
> -#ifdef AFS_OBSD_ENV
> +#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
>      cacheInode = VTOI(filevp)->i_number;
>      cacheDev.mp = filevp->v_mount;
>      cacheDev.held_vnode = filevp;
> +#ifdef AFS_OBSD_ENV
>      AFS_HOLD(filevp);		/* Make sure mount point stays busy. XXX */
>  #else
> +    vref(filevp);
> +    afs_cacheVfsp = filevp->v_vfsp;
> +#endif
> +#else
>  #if defined(AFS_SGI62_ENV) || defined(AFS_HAVE_VXFS) ||
> defined(AFS_DARWIN_ENV) afs_InitDualFSCacheOps(filevp);
>  #endif
>      cacheInode = afs_vnodeToInumber(filevp);
>      cacheDev.dev = afs_vnodeToDev(filevp);
>      afs_cacheVfsp = filevp->v_vfsp;
> -#endif /* AFS_OBSD_ENV */
> +#endif /* !AFS_[FO]BSD_ENV */
>  #endif /* AFS_LINUX20_ENV */
>      AFS_RELE(filevp);
>  #endif /* AFS_LINUX22_ENV */
> @@ -494,10 +499,12 @@
>      RWLOCK_INIT(&afs_icl_lock, "afs_icl_lock");
>      RWLOCK_INIT(&afs_xinterface, "afs_xinterface");
>      LOCK_INIT(&afs_puttofileLock, "afs_puttofileLock");
> +#ifndef AFS_FBSD_ENV
>  #ifndef	AFS_AIX32_ENV
>      LOCK_INIT(&osi_fsplock, "osi_fsplock");
>  #endif
>      LOCK_INIT(&osi_flplock, "osi_flplock");
> +#endif
>      RWLOCK_INIT(&afs_xconn, "afs_xconn");
>
>      afs_CellInit();
> @@ -669,11 +676,19 @@
>  	afs_cacheFiles = afs_cacheBlocks = 0;
>  	pag_epoch = maxIHint = nihints = usedihint = 0;
>  	pagCounter = 0;
> +#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
>  #ifdef AFS_OBSD_ENV
>  	AFS_RELE(volumeVnode);	/* let it go, finally. */
> +#else
> +	vrele(volumeVnode);
> +#endif
>  	volumeVnode = NULL;
>  	if (cacheDev.held_vnode) {
> +#ifdef AFS_OBSD_ENV
>  	    AFS_RELE(cacheDev.held_vnode);
> +#else
> +	    vrele(cacheDev.held_vnode);
> +#endif
>  	    cacheDev.held_vnode = NULL;
>  	}
>  #endif
> Index: src/afs/afs_osi.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/afs_osi.c,v
> retrieving revision 1.38
> diff -u -r1.38 afs_osi.c
> --- src/afs/afs_osi.c	27 Aug 2003 21:43:16 -0000	1.38
> +++ src/afs/afs_osi.c	8 Oct 2003 05:09:38 -0000
> @@ -57,6 +57,8 @@
>  #elif defined(AFS_OSF_ENV)
>      usimple_lock_init(&afs_global_lock);
>      afs_global_owner = (thread_t) 0;
> +#elif defined(AFS_FBSD50_ENV)
> +    mtx_init(&afs_global_mtx, "AFS global lock", NULL, MTX_DEF);
>  #elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
>      lockinit(&afs_global_lock, PLOCK, "afs global lock", 0, 0);
>      afs_global_owner = 0;
> @@ -433,6 +435,8 @@
>      AFS_STATS(afs_stats_cmperf.OutStandingMemUsage += x);
>  #ifdef AFS_LINUX20_ENV
>      return osi_linux_alloc(x, 1);
> +#elif defined(AFS_FBSD_ENV)
> +    return osi_fbsd_alloc(x, 1);
>  #else
>      size = x;
>      tm = (struct osimem *)AFS_KALLOC(size);
> @@ -479,6 +483,8 @@
>      AFS_STATS(afs_stats_cmperf.OutStandingMemUsage -= asize);
>  #if defined(AFS_LINUX20_ENV)
>      osi_linux_free(x);
> +#elif defined(AFS_FBSD_ENV)
> +    osi_fbsd_free(x);
>  #else
>      AFS_KFREE((struct osimem *)x, asize);
>  #endif
> Index: src/afs/afs_osi.h
> ===================================================================
> RCS file: /cvs/openafs/src/afs/afs_osi.h,v
> retrieving revision 1.19
> diff -u -r1.19 afs_osi.h
> --- src/afs/afs_osi.h	29 Aug 2003 22:00:04 -0000	1.19
> +++ src/afs/afs_osi.h	8 Oct 2003 05:09:38 -0000
> @@ -13,6 +13,10 @@
>  #include "h/types.h"
>  #include "h/param.h"
>
> +#ifdef AFS_FBSD50_ENV
> +#include <sys/condvar.h>
> +#endif
> +
>  #ifdef AFS_LINUX20_ENV
>  #ifndef _LINUX_CODA_FS_I
>  #define _LINUX_CODA_FS_I
> @@ -68,11 +72,13 @@
>  };
>
>  struct osi_dev {
> -#ifdef AFS_OBSD_ENV
> +#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
>      struct mount *mp;
>      struct vnode *held_vnode;
> +/* see if we need this...
>  #elif defined(AFS_FBSD50_ENV)
>      struct cdev *dev;
> +*/
>  #elif defined(AFS_AIX42_ENV)
>      dev_t dev;
>  #else
> @@ -81,7 +87,12 @@
>  };
>
>  struct afs_osi_WaitHandle {
> +#ifdef AFS_FBSD50_ENV
> +    struct cv wh_condvar;
> +    int wh_inited;		/* XXX */
> +#else
>      caddr_t proc;		/* process waiting */
> +#endif
>  };
>
>  #define	osi_SetFileProc(x,p)	((x)->proc=(p))
> Index: src/afs/afs_osi_alloc.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/afs_osi_alloc.c,v
> retrieving revision 1.9
> diff -u -r1.9 afs_osi_alloc.c
> --- src/afs/afs_osi_alloc.c	15 Jul 2003 23:14:12 -0000	1.9
> +++ src/afs/afs_osi_alloc.c	8 Oct 2003 05:09:39 -0000
> @@ -19,6 +19,7 @@
>  #include "afsincludes.h"	/* Afs-based standard headers */
>  #include "afs/afs_stats.h"	/* afs statistics */
>
> +#ifndef AFS_FBSD_ENV
>  #ifdef AFS_AIX41_ENV
>  #include "sys/lockl.h"
>  #include "sys/sleep.h"
> @@ -368,3 +369,4 @@
>  	LOCK_INIT(&osi_flplock, "osi_flplock");
>      }
>  }
> +#endif
> Index: src/afs/afs_prototypes.h
> ===================================================================
> RCS file: /cvs/openafs/src/afs/afs_prototypes.h,v
> retrieving revision 1.42
> diff -u -r1.42 afs_prototypes.h
> --- src/afs/afs_prototypes.h	15 Jul 2003 23:14:12 -0000	1.42
> +++ src/afs/afs_prototypes.h	8 Oct 2003 05:09:39 -0000
> @@ -465,8 +465,12 @@
>  extern void afs_osi_MaskSignals(void);
>  extern void afs_osi_UnmaskRxkSignals(void);
>  extern void *afs_osi_Alloc(size_t x);
> +#ifndef afs_osi_Alloc_NoSleep
>  extern void *afs_osi_Alloc_NoSleep(size_t x);
> +#endif
> +#ifndef afs_osi_Free
>  extern void afs_osi_Free(void *x, size_t asize);
> +#endif
>  extern void afs_osi_FreeStr(char *x);
>  extern void osi_Init(void);
>  extern int osi_Active(register struct vcache *avc);
> @@ -503,9 +507,11 @@
>  extern afs_int32 PagInCred(const struct AFS_UCRED *cred);
>
>  /* afs_osi_alloc.c */
> +#ifndef AFS_FBSD_ENV
>  extern afs_int32 afs_preallocs;
>  extern afs_lock_t osi_fsplock;
>  extern afs_lock_t osi_flplock;
> +#endif
>  extern void osi_FreeLargeSpace(void *adata);
>  extern void osi_FreeMediumSpace(void *adata);
>  extern void osi_FreeSmallSpace(void *adata);
> Index: src/afs/afs_vcache.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/afs_vcache.c,v
> retrieving revision 1.55
> diff -u -r1.55 afs_vcache.c
> --- src/afs/afs_vcache.c	3 Sep 2003 16:47:15 -0000	1.55
> +++ src/afs/afs_vcache.c	8 Oct 2003 05:09:42 -0000
> @@ -153,7 +153,7 @@
>  	afs_osi_Free(avc->linkData, strlen(avc->linkData) + 1);
>  	avc->linkData = NULL;
>      }
> -#if defined(AFS_OBSD_ENV)
> +#if defined(AFS_XBSD_ENV)
>      /* OK, there are no internal vrefCounts, so there shouldn't
>       * be any more refs here. */
>      if (avc->v) {
> @@ -801,36 +801,6 @@
>  		    continue;	/* start over - may have raced. */
>  		}
>  	    }
> -#elif defined(AFS_FBSD50_ENV)
> -	    if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
> -		&& (tvc->states & CUnlinkedDel) == 0) {
> -		if (!(VOP_LOCK(&tvc->v, LK_EXCLUSIVE, curthread))) {
> -		    if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
> -			&& (tvc->states & CUnlinkedDel) == 0) {
> -			VREFCOUNT_DEC(tvc);
> -			AFS_GUNLOCK();	/* perhaps inline inactive for locking */
> -			VOP_INACTIVE(&tvc->v, curthread);
> -			AFS_GLOCK();
> -		    } else {
> -			VOP_UNLOCK(&tvc->v, 0, curthread);
> -		    }
> -		}
> -	    }
> -#elif defined(AFS_FBSD_ENV) && !defined(AFS_FBSD50_ENV)
> -	    if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
> -		&& (tvc->states & CUnlinkedDel) == 0) {
> -		if (!(VOP_LOCK(&tvc->v, LK_EXCLUSIVE, curproc))) {
> -		    if (VREFCOUNT(tvc) == 1 && tvc->opens == 0
> -			&& (tvc->states & CUnlinkedDel) == 0) {
> -			VREFCOUNT_DEC(tvc);
> -			AFS_GUNLOCK();	/* perhaps inline inactive for locking */
> -			VOP_INACTIVE(&tvc->v, curproc);
> -			AFS_GLOCK();
> -		    } else {
> -			VOP_UNLOCK(&tvc->v, 0, curproc);
> -		    }
> -		}
> -	    }
>  #elif defined(AFS_LINUX22_ENV)
>  	    if (tvc != afs_globalVp && VREFCOUNT(tvc) && tvc->opens == 0)
>  		afs_TryFlushDcacheChildren(tvc);
> @@ -838,12 +808,13 @@
>
>  	    if (VREFCOUNT(tvc) == 0 && tvc->opens == 0
>  		&& (tvc->states & CUnlinkedDel) == 0) {
> -#ifdef AFS_OBSD_ENV
> +#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
>  		/*
>  		 * vgone() reclaims the vnode, which calls afs_FlushVCache(),
>  		 * then it puts the vnode on the free list.
>  		 * If we don't do this we end up with a cleaned vnode that's
>  		 * not on the free list.
> +		 * XXX assume FreeBSD is the same for now.
>  		 */
>  		vgone(AFSTOV(tvc));
>  		code = fv_slept = 0;
> @@ -907,7 +878,7 @@
>      vm_info_ptr = tvc->v.v_vm_info;
>  #endif /* AFS_MACH_ENV */
>
> -#if defined(AFS_OBSD_ENV)
> +#if defined(AFS_OBSD_ENV) || defined(AFS_FBSD_ENV)
>      if (tvc->v)
>  	panic("afs_NewVCache(): free vcache with vnode attached");
>  #endif
> @@ -931,6 +902,32 @@
>      afs_nbsd_getnewvnode(tvc);	/* includes one refcount */
>      lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
>  #endif
> +#ifdef AFS_FBSD_ENV
> +    {
> +	struct vnode *vp;
> +
> +	AFS_GUNLOCK();
> +	if (getnewvnode("afs", afs_globalVFS, afs_vnodeop_p, &vp))
> +	    panic("afs getnewvnode");	/* can't happen */
> +	AFS_GLOCK();
> +	if (tvc->v != NULL) {
> +	    /* I'd like to know if this ever happens...
> +	       We don't drop global for the rest of this function,
> +	       so if we do lose the race, the other thread should
> +	       have found the same vnode and finished initializing
> +	       the vcache entry.  Is it conceivable that this vcache
> +	       entry could be recycled during this interval?  If so,
> +	       then there probably needs to be some sort of additional
> +	       mutual exclusion (an Embryonic flag would suffice).
> +		-GAW */
> +	    printf("afs_NewVCache: lost the race\n");
> +	    return (tvc);
> +	}
> +	tvc->v = vp;
> +	tvc->v->v_data = tvc;
> +	lockinit(&tvc->rwlock, PINOD, "vcache", 0, 0);
> +    }
> +#endif
>      tvc->parentVnode = 0;
>      tvc->mvid = NULL;
>      tvc->linkData = NULL;
> @@ -955,9 +952,9 @@
>      /* Hold it for the LRU (should make count 2) */
>      VN_HOLD(AFSTOV(tvc));
>  #else /* AFS_OSF_ENV */
> -#ifndef AFS_OBSD_ENV
> +#if !defined(AFS_OBSD_ENV) && !defined(AFS_FBSD_ENV)
>      VREFCOUNT_SET(tvc, 1);	/* us */
> -#endif /* AFS_OBSD_ENV */
> +#endif /* AFS_[FO]BSD_ENV */
>  #endif /* AFS_OSF_ENV */
>  #ifdef	AFS_AIX32_ENV
>      LOCK_INIT(&tvc->pvmlock, "vcache pvmlock");
> @@ -1038,14 +1035,6 @@
>      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(AFSTOV(tvc));
> -    tvc->v.v_data = tvc;
> -    tvc->v.v_tag = VT_AFS;
> -    tvc->v.v_usecount++;	/* steal an extra ref for now so vfree never
> happens */ -    /* This extra ref is dealt with above... */
> -#endif
>      /*
>       * The proper value for mvstat (for root fids) is setup by the caller.
>       */
> @@ -1798,6 +1787,40 @@
>      VOP_LOCK(AFSTOV(tvc), LK_EXCLUSIVE | LK_RETRY, curproc);
>      uvm_vnp_uncache(AFSTOV(tvc));
>      VOP_UNLOCK(AFSTOV(tvc), 0, curproc);
> +#endif
> +#ifdef AFS_FBSD_ENV
> +    /*
> +     * XXX - I really don't like this.  Should try to understand better.
> +     * It seems that sometimes, when we get called, we already hold the
> +     * lock on the vnode (e.g., from afs_getattr via afs_VerifyVCache).
> +     * We can't drop the vnode lock, because that could result in a race.
> +     * Sometimes, though, we get here and don't hold the vnode lock.
> +     * I hate code paths that sometimes hold locks and sometimes don't.
> +     * In any event, the dodge we use here is to check whether the vnode
> +     * is locked, and if it isn't, then we gain and drop it around the
> call +     * to vinvalbuf; otherwise, we leave it alone.
> +     */
> +    {
> +	struct vnode *vp;
> +	int iheldthelock;
> +
> +	vp = AFSTOV(tvc);
> +#ifdef AFS_FBSD50_ENV
> +	iheldthelock = VOP_ISLOCKED(vp, curthread);
> +	if (!iheldthelock)
> +	    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
> +	vinvalbuf(vp, V_SAVE, curthread->td_ucred, curthread, PINOD, 0);
> +	if (!iheldthelock)
> +	    VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
> +#else
> +	iheldthelock = VOP_ISLOCKED(vp, curproc);
> +	if (!iheldthelock)
> +	    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
> +	vinvalbuf(vp, V_SAVE, curthread->td_ucred, curproc, PINOD, 0);
> +	if (!iheldthelock)
> +	    VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc);
> +#endif
> +    }
>  #endif
>
>      ObtainWriteLock(&afs_xcbhash, 464);
> Index: src/afs/FBSD/osi_file.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/FBSD/osi_file.c,v
> retrieving revision 1.12
> diff -u -r1.12 osi_file.c
> --- src/afs/FBSD/osi_file.c	9 Sep 2003 21:14:34 -0000	1.12
> +++ src/afs/FBSD/osi_file.c	8 Oct 2003 05:09:43 -0000
> @@ -73,7 +73,9 @@
>      MObtainWriteLock(&afs_xosi, 320);
>      AFS_GUNLOCK();
>  #if defined(AFS_FBSD50_ENV)
> +    vn_lock(afile->vnode, LK_EXCLUSIVE | LK_RETRY, curthread);
>      code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
> +    VOP_UNLOCK(afile->vnode, LK_EXCLUSIVE, curthread);
>  #else
>      code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
>  #endif
> @@ -104,25 +106,41 @@
>  osi_UFSTruncate(register struct osi_file *afile, afs_int32 asize)
>  {
>      struct vattr tvattr;
> +    struct vnode *vp;
>      register afs_int32 code;
> -    struct osi_stat tstat;
>      AFS_STATCNT(osi_Truncate);
>
> -    /* This routine only shrinks files, and most systems
> +    MObtainWriteLock(&afs_xosi, 321);
> +    vp = afile->vnode;
> +    /*
> +     * This routine only shrinks files, and most systems
>       * have very slow truncates, even when the file is already
>       * small enough.  Check now and save some time.
>       */
> -    code = afs_osi_Stat(afile, &tstat);
> -    if (code || tstat.size <= asize)
> -	return code;
> -    MObtainWriteLock(&afs_xosi, 321);
> +    AFS_GUNLOCK();
> +#if defined(AFS_FBSD50_ENV)
> +    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curthread);
> +    code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
> +#else
> +    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
> +    code = VOP_GETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
> +#endif
> +    if (code != 0 || tvattr.va_size <= asize)
> +	goto out;
> +
>      VATTR_NULL(&tvattr);
>      tvattr.va_size = asize;
> -    AFS_GUNLOCK();
>  #if defined(AFS_FBSD50_ENV)
> -    code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp, curthread);
> +    code = VOP_SETATTR(vp, &tvattr, afs_osi_credp, curthread);
> +#else
> +    code = VOP_SETATTR(vp, &tvattr, afs_osi_credp, curproc);
> +#endif
> +
> +out:
> +#if defined(AFS_FBSD50_ENV)
> +    VOP_UNLOCK(vp, LK_EXCLUSIVE, curthread);
>  #else
> -    code = VOP_SETATTR(afile->vnode, &tvattr, afs_osi_credp, curproc);
> +    VOP_UNLOCK(vp, LK_EXCLUSIVE, curproc);
>  #endif
>      AFS_GLOCK();
>      MReleaseWriteLock(&afs_xosi);
> Index: src/afs/FBSD/osi_machdep.h
> ===================================================================
> RCS file: /cvs/openafs/src/afs/FBSD/osi_machdep.h,v
> retrieving revision 1.7
> diff -u -r1.7 osi_machdep.h
> --- src/afs/FBSD/osi_machdep.h	15 Jul 2003 23:14:19 -0000	1.7
> +++ src/afs/FBSD/osi_machdep.h	8 Oct 2003 05:09:43 -0000
> @@ -21,6 +21,7 @@
>
>  #include <sys/lock.h>
>  #include <sys/time.h>
> +#include <sys/mutex.h>
>  /* #include <kern/sched_prim.h> */
>  /* #include <sys/unix_defs.h> */
>
> @@ -42,7 +43,13 @@
>  #define iodone biodone
>  #endif
>
> -#define osi_vnhold(avc,r) do { VN_HOLD((struct vnode *)(avc)); } while (0)
> +#define osi_vnhold(avc,r)	vref(AFSTOV(avc))
> +#undef vSetVfsp
> +#define vSetVfsp(vc, vfsp)	AFSTOV(vc)->v_mount = (vfsp)
> +#undef vSetType
> +#define vSetType(vc, type)	AFSTOV(vc)->v_type = (type)
> +#undef vType
> +#define	vType(vc)		AFSTOV(vc)->v_type
>
>  #undef gop_lookupname
>  #define gop_lookupname osi_lookupname
> @@ -52,7 +59,9 @@
>  #define afs_strcat(s1, s2)	strcat((s1), (s2))
>
>  #ifdef KERNEL
> -extern struct lock afs_global_lock;
> +
> +#undef afs_osi_Alloc_NoSleep
> +#define afs_osi_Alloc_NoSleep(size) osi_fbsd_alloc((size), 0)
>
>  #if defined(AFS_FBSD50_ENV)
>  #define VT_AFS		"afs"
> @@ -64,24 +73,13 @@
>  #define simple_unlock(x) mtx_unlock(x)
>  #define        gop_rdwr(rw,gp,base,len,offset,segflg,unit,cred,aresid) \
>   
> vn_rdwr((rw),(gp),(base),(len),(offset),(segflg),(unit),(cred),(cred),(ares
>id), curthread) -extern struct thread *afs_global_owner;
> -#define AFS_GLOCK() \
> -    do { \
> -        osi_Assert(curthread); \
> - 	lockmgr(&afs_global_lock, LK_EXCLUSIVE, 0, curthread); \
> -        osi_Assert(afs_global_owner == 0); \
> -   	afs_global_owner = curthread; \
> -    } while (0)
> -#define AFS_GUNLOCK() \
> -    do { \
> -        osi_Assert(curthread); \
> - 	osi_Assert(afs_global_owner == curthread); \
> -        afs_global_owner = 0; \
> -        lockmgr(&afs_global_lock, LK_RELEASE, 0, curthread); \
> -    } while(0)
> -#define ISAFS_GLOCK() (afs_global_owner == curthread && curthread)
> +extern struct mtx afs_global_mtx;
> +#define AFS_GLOCK() mtx_lock(&afs_global_mtx)
> +#define AFS_GUNLOCK() mtx_unlock(&afs_global_mtx)
> +#define ISAFS_GLOCK() (mtx_owned(&afs_global_mtx))
>
>  #else /* FBSD50 */
> +extern struct lock afs_global_lock;
>
>  #define osi_curcred()	(curproc->p_cred->pc_ucred)
>  #define getpid()	curproc
> Index: src/afs/FBSD/osi_misc.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/FBSD/osi_misc.c,v
> retrieving revision 1.8
> diff -u -r1.8 osi_misc.c
> --- src/afs/FBSD/osi_misc.c	15 Jul 2003 23:14:19 -0000	1.8
> +++ src/afs/FBSD/osi_misc.c	8 Oct 2003 05:09:43 -0000
> @@ -53,7 +53,12 @@
>  	       struct vnode **dirvpp, struct vnode **vpp)
>  {
>      struct nameidata n;
> -    int flags, error;
> +    int flags, error, wasowned;
> +
> +    wasowned = mtx_owned(&afs_global_mtx);
> +    if (wasowned)
> +	mtx_unlock(&afs_global_mtx);
> +
>      flags = 0;
>      flags = LOCKLEAF;
>      if (followlink)
> @@ -62,8 +67,11 @@
>  	flags |= NOFOLLOW;
>      /*   if (dirvpp) flags|=WANTPARENT; *//* XXX LOCKPARENT? */
>      NDINIT(&n, LOOKUP, flags, seg, aname, curproc);
> -    if (error = namei(&n))
> +    if ((error = namei(&n)) != 0) {
> +	if (wasowned)
> +	    mtx_lock(&afs_global_mtx);
>  	return error;
> +    }
>      *vpp = n.ni_vp;
>  /*
>     if (dirvpp)
> @@ -72,6 +80,8 @@
>      /* should we do this? */
>      VOP_UNLOCK(n.ni_vp, 0, curproc);
>      NDFREE(&n, NDF_ONLY_PNBUF);
> +    if (wasowned)
> +	mtx_lock(&afs_global_mtx);
>      return 0;
>  }
>
> @@ -102,4 +112,73 @@
>      resettodr();
>      AFS_GLOCK();
>  #endif
> +}
> +
> +/*
> + * Replace all of the bogus special-purpose memory allocators...
> + */
> +void *
> +osi_fbsd_alloc(size_t size, int dropglobal)
> +{
> +	void *rv;
> +	int wasowned;
> +
> +	if (dropglobal) {
> +		wasowned = mtx_owned(&afs_global_mtx);
> +		if (wasowned)
> +			mtx_unlock(&afs_global_mtx);
> +		rv = malloc(size, M_AFS, M_WAITOK);
> +		if (wasowned)
> +			mtx_lock(&afs_global_mtx);
> +	} else
> +		rv = malloc(size, M_AFS, M_NOWAIT);
> +
> +	return (rv);
> +}
> +
> +void
> +osi_fbsd_free(void *p)
> +{
> +
> +	free(p, M_AFS);
> +}
> +
> +void
> +osi_AllocMoreSSpace(afs_int32 preallocs)
> +{
> +	;
> +}
> +
> +void
> +osi_FreeLargeSpace(void *p)
> +{
> +	osi_fbsd_free(p);
> +}
> +
> +void
> +osi_FreeSmallSpace(void *p)
> +{
> +	osi_fbsd_free(p);
> +}
> +
> +void *
> +osi_AllocLargeSpace(size_t size)
> +{
> +	AFS_ASSERT_GLOCK();
> +	AFS_STATCNT(osi_AllocLargeSpace);
> +	return (osi_fbsd_alloc(size, 1));
> +}
> +
> +void *
> +osi_AllocSmallSpace(size_t size)
> +{
> +	AFS_ASSERT_GLOCK();
> +	AFS_STATCNT(osi_AllocSmallSpace);
> +	return (osi_fbsd_alloc(size, 1));
> +}
> +
> +void
> +shutdown_osinet(void)
> +{
> +	;
>  }
> Index: src/afs/FBSD/osi_module.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/FBSD/osi_module.c,v
> retrieving revision 1.4
> diff -u -r1.4 osi_module.c
> --- src/afs/FBSD/osi_module.c	15 Jul 2003 23:14:20 -0000	1.4
> +++ src/afs/FBSD/osi_module.c	8 Oct 2003 05:09:43 -0000
> @@ -60,8 +60,10 @@
>  	vfs_register(&afs_vfsconf);	/* doesn't fail */
>  	vfs_add_vnodeops(&afs_vnodeop_opv_desc);
>  	osi_Init();
> +#ifdef DO_NOT_EVER_EVER_DO_THIS
>  	sysent[SYS_setgroups].sy_call = Afs_xsetgroups;
>  	sysent[SYS_ioctl].sy_call = afs_xioctl;
> +#endif
>  	old_handler = sysent[AFS_SYSCALL].sy_call;
>  	sysent[AFS_SYSCALL].sy_call = afs3_syscall;
>  	sysent[AFS_SYSCALL].sy_narg = 5;
> Index: src/afs/FBSD/osi_prototypes.h
> ===================================================================
> RCS file: /cvs/openafs/src/afs/FBSD/osi_prototypes.h,v
> retrieving revision 1.4
> diff -u -r1.4 osi_prototypes.h
> --- src/afs/FBSD/osi_prototypes.h	15 Jul 2003 23:14:20 -0000	1.4
> +++ src/afs/FBSD/osi_prototypes.h	8 Oct 2003 05:09:43 -0000
> @@ -20,8 +20,14 @@
>  /* osi_misc.c */
>  extern int osi_lookupname(char *aname, enum uio_seg seg, int followlink,
>  			  struct vnode **dirvpp, struct vnode **vpp);
> +extern void *osi_fbsd_alloc(size_t size, int dropglobal);
> +extern void osi_fbsd_free(void *p);
>
>  /* osi_vfsops.c */
> +#ifdef AFS_FBSD50_ENV
> +extern int afs_statfs(struct mount *mp, struct statfs *abp, struct thread
> *th); +#else
>  extern int afs_statfs(struct mount *mp, struct statfs *abp, struct proc
> *p); +#endif
>
>  #endif /* _OSI_PROTO_H_ */
> Index: src/afs/FBSD/osi_sleep.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/FBSD/osi_sleep.c,v
> retrieving revision 1.10
> diff -u -r1.10 osi_sleep.c
> --- src/afs/FBSD/osi_sleep.c	15 Jul 2003 23:14:20 -0000	1.10
> +++ src/afs/FBSD/osi_sleep.c	8 Oct 2003 05:09:43 -0000
> @@ -18,32 +18,31 @@
>  #include "afsincludes.h"	/* Afs-based standard headers */
>  #include "afs/afs_stats.h"	/* afs statistics */
>
> -
> -
> -static int osi_TimedSleep(char *event, afs_int32 ams, int aintok);
> -
> -static char waitV;
> -
> -
>  void
>  afs_osi_InitWaitHandle(struct afs_osi_WaitHandle *achandle)
>  {
>      AFS_STATCNT(osi_InitWaitHandle);
> -    achandle->proc = (caddr_t) 0;
> +    cv_init(&achandle->wh_condvar, "afscondvar");
> +    achandle->wh_inited = 1;
>  }
>
>  /* cancel osi_Wait */
> +/* XXX
> + * I can't tell -- is this supposed to be cv_signal() or
> cv_waitq_remove()? + * Or perhaps cv_broadcast()?
> + * Assuming cv_signal() is the desired meaning.  -GAW
> + */
>  void
>  afs_osi_CancelWait(struct afs_osi_WaitHandle *achandle)
>  {
> -    caddr_t proc;
>
>      AFS_STATCNT(osi_CancelWait);
> -    proc = achandle->proc;
> -    if (proc == 0)
> +    /* XXX should not be necessary */
> +    if (!achandle->wh_inited)
>  	return;
> -    achandle->proc = (caddr_t) 0;	/* so dude can figure out he was
> signalled */ -    afs_osi_Wakeup(&waitV);
> +
> +    AFS_ASSERT_GLOCK();
> +    cv_signal(&achandle->wh_condvar);
>  }
>
>  /* afs_osi_Wait
> @@ -54,31 +53,36 @@
>  afs_osi_Wait(afs_int32 ams, struct afs_osi_WaitHandle *ahandle, int
> aintok) {
>      int code;
> -    afs_int32 endTime;
> +    struct timeval tv;
> +    int ticks;
>
>      AFS_STATCNT(osi_Wait);
> -    endTime = osi_Time() + (ams / 1000);
> -    if (ahandle)
> -	ahandle->proc = (caddr_t) curproc;
> -    do {
> -	AFS_ASSERT_GLOCK();
> -	code = 0;
> -	code = osi_TimedSleep(&waitV, ams, aintok);
>
> -	if (code)
> -	    break;		/* if something happened, quit now */
> -	/* if we we're cancelled, quit now */
> -	if (ahandle && (ahandle->proc == (caddr_t) 0)) {
> -	    /* we've been signalled */
> -	    break;
> -	}
> -    } while (osi_Time() < endTime);
> +    tv.tv_sec = ams / 1000;
> +    tv.tv_usec = (ams % 1000) * 1000;
> +    ticks = tvtohz(&tv);
> +
> +    AFS_ASSERT_GLOCK();
> +    if (ahandle == NULL) {
> +	/* This is nasty and evil and rude. */
> +	code = msleep(&tv, &afs_global_mtx, (aintok ? PPAUSE|PCATCH : PVFS),
> +	    "afswait", ticks);
> +    } else {
> +	if (!ahandle->wh_inited)
> +	    afs_osi_InitWaitHandle(ahandle);	/* XXX should not be needed */
> +
> +	if (aintok)
> +	    code = cv_timedwait_sig(&ahandle->wh_condvar, &afs_global_mtx,
> +		ticks);
> +	else
> +	    code = cv_timedwait(&ahandle->wh_condvar, &afs_global_mtx, ticks);
> +    }
>      return code;
>  }
>
> -
> -
> -
> +/*
> + * All this gluck should probably also be replaced with CVs.
> + */
>  typedef struct afs_event {
>      struct afs_event *next;	/* next in hash chain */
>      char *event;		/* lwp event: an address */
> @@ -140,9 +144,7 @@
>      seq = evp->seq;
>      while (seq == evp->seq) {
>  	AFS_ASSERT_GLOCK();
> -	AFS_GUNLOCK();
> -	tsleep(event, PVFS, "afs_osi_Sleep", 0);
> -	AFS_GLOCK();
> +	msleep(event, &afs_global_mtx, PVFS, "afsslp", 0);
>      }
>      relevent(evp);
>  }
> @@ -153,42 +155,6 @@
>      afs_osi_Sleep(event);
>      return 0;
>  }
> -
> -/* osi_TimedSleep
> - *
> - * Arguments:
> - * event - event to sleep on
> - * ams --- max sleep time in milliseconds
> - * aintok - 1 if should sleep interruptibly
> - *
> - * Returns 0 if timeout and EINTR if signalled.
> - */
> -static int
> -osi_TimedSleep(char *event, afs_int32 ams, int aintok)
> -{
> -    int code = 0;
> -    struct afs_event *evp;
> -    int ticks;
> -    int seq, prio;
> -
> -    ticks = (ams * afs_hz) / 1000;
> -
> -
> -    evp = afs_getevent(event);
> -    seq = evp->seq;
> -    AFS_GUNLOCK();
> -    if (aintok)
> -	prio = PCATCH | PPAUSE;
> -    else
> -	prio = PVFS;
> -    code = tsleep(event, prio, "afs_osi_TimedSleep", ticks);
> -    AFS_GLOCK();
> -    if (seq == evp->seq)
> -	code = EINTR;
> -    relevent(evp);
> -    return code;
> -}
> -
>
>  int
>  afs_osi_Wakeup(void *event)
> Index: src/afs/FBSD/osi_vfsops.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/FBSD/osi_vfsops.c,v
> retrieving revision 1.14
> diff -u -r1.14 osi_vfsops.c
> --- src/afs/FBSD/osi_vfsops.c	15 Jul 2003 23:14:20 -0000	1.14
> +++ src/afs/FBSD/osi_vfsops.c	8 Oct 2003 05:09:43 -0000
> @@ -16,48 +16,42 @@
>  struct mount *afs_globalVFS = 0;
>  int afs_pbuf_freecnt = -1;
>
> +#ifdef AFS_FBSD50_ENV
> +#define	THREAD_OR_PROC struct thread *p
> +#else
> +#define	THREAD_OR_PROC struct proc *p
> +#endif
> +
>  int
> -afs_quotactl()
> +afs_quotactl(struct mount *mp, int c, uid_t u, caddr_t data,
> THREAD_OR_PROC) {
>      return EOPNOTSUPP;
>  }
>
>  int
> -afs_fhtovp(mp, fhp, vpp)
> -     struct mount *mp;
> -     struct fid *fhp;
> -     struct vnode **vpp;
> +afs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
>  {
>
>      return (EINVAL);
>  }
>
>  int
> -afs_vptofh(vp, fhp)
> -     struct vnode *vp;
> -     struct fid *fhp;
> +afs_vptofh(struct vnode *vp, struct fid *fhp)
>  {
>
>      return (EINVAL);
>  }
>
>  int
> -afs_start(mp, flags, p)
> -     struct mount *mp;
> -     int flags;
> -     struct proc *p;
> +afs_start(struct mount *mp, int flags, THREAD_OR_PROC)
>  {
>      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;
> +afs_mount(struct mount *mp, char *path, caddr_t data, struct nameidata
> *ndp, +	THREAD_OR_PROC)
>  {
>      /* ndp contains the mounted-from device.  Just ignore it.
>       * we also don't care about our proc struct. */
> @@ -91,12 +85,16 @@
>  }
>
>  int
> -afs_unmount(mp, flags, p)
> -     struct mount *mp;
> -     int flags;
> -     struct proc *p;
> +afs_unmount(struct mount *mp, int flags, THREAD_OR_PROC)
>  {
>
> +    /*
> +     * Releaase any remaining vnodes on this mount point.
> +     * The `1' means that we hold one extra reference on
> +     * the root vnode (this is just a guess right now).
> +     * This has to be done outside the global lock.
> +     */
> +    vflush(mp, 1, (flags & MNT_FORCE) ? FORCECLOSE : 0);
>      AFS_GLOCK();
>      AFS_STATCNT(afs_unmount);
>      afs_globalVFS = 0;
> @@ -114,10 +112,10 @@
>      register struct vcache *tvp = 0;
>  #ifdef AFS_FBSD50_ENV
>      struct thread *td = curthread;
> -    struct ucred cr = *td->td_ucred;
> +    struct ucred *cr = crhold(td->td_ucred);
>  #else
>      struct proc *p = curproc;
> -    struct ucred cr = *p->p_cred->pc_ucred;
> +    struct ucred *cr = crhold(p->p_cred->pc_ucred);
>  #endif
>
>      AFS_GLOCK();
> @@ -126,12 +124,14 @@
>  	tvp = afs_globalVp;
>  	error = 0;
>      } else {
> +tryagain:
>  	if (afs_globalVp) {
>  	    afs_PutVCache(afs_globalVp);
> +	    /* vrele() needed here or not? */
>  	    afs_globalVp = NULL;
>  	}
>
> -	if (!(error = afs_InitReq(&treq, &cr)) && !(error = afs_CheckInit())) {
> +	if (!(error = afs_InitReq(&treq, cr)) && !(error = afs_CheckInit())) {
>  	    tvp = afs_GetVCache(&afs_rootFid, &treq, NULL, NULL);
>  	    /* we really want this to stay around */
>  	    if (tvp)
> @@ -141,34 +141,41 @@
>  	}
>      }
>      if (tvp) {
> -	osi_vnhold(tvp, 0);
> +	struct vnode *vp = AFSTOV(tvp);
> +
> +	ASSERT_VI_UNLOCKED(vp, "afs_root");
>  	AFS_GUNLOCK();
> +	/*
> +	 * I'm uncomfortable about this.  Shouldn't this happen at a
> +	 * higher level, and shouldn't we busy the top-level directory
> +	 * to prevent recycling?
> +	 */
>  #ifdef AFS_FBSD50_ENV
> -	vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, td);
> +	error = vget(vp, LK_EXCLUSIVE | LK_RETRY, td);
> +	vp->v_vflag |= VV_ROOT;
>  #else
> -	vn_lock(AFSTOV(tvp), LK_EXCLUSIVE | LK_RETRY, p);
> +	error = vget(vp, LK_EXCLUSIVE | LK_RETRY, p);
> +	vp->v_flag |= VROOT;
>  #endif
>  	AFS_GLOCK();
> +	if (error != 0)
> +		goto tryagain;
> +
>  	afs_globalVFS = mp;
> -	*vpp = AFSTOV(tvp);
> -	tvp->v.v_flag |= VROOT;
> +	*vpp = vp;
>      }
>
>      afs_Trace2(afs_iclSetp, CM_TRACE_VFSROOT, ICL_TYPE_POINTER, *vpp,
>  	       ICL_TYPE_INT32, error);
>      AFS_GUNLOCK();
> +    crfree(cr);
>      return error;
>  }
>
> +#ifndef AFS_FBSD50_ENV
>  int
> -afs_vget(mp, lfl, vp)
> -     struct mount *mp;
> -     struct vnode *vp;
> -     int lfl;
> +afs_vget(struct mount *mp, ino_t ino, int flags, struct vnode *vp)
>  {
> -#ifdef AFS_FBSD50_ENV
> -    return EOPNOTSUPP;
> -#else
>      int error;
>
>      printf("vget called. help!\n");
> @@ -180,11 +187,11 @@
>      if (!error)
>  	insmntque(vp, afs_globalVFS);	/* take off free list */
>      return error;
> -#endif
>  }
> +#endif
>
>  int
> -afs_statfs(struct mount *mp, struct statfs *abp, struct proc *p)
> +afs_statfs(struct mount *mp, struct statfs *abp, THREAD_OR_PROC)
>  {
>      AFS_GLOCK();
>      AFS_STATCNT(afs_statfs);
> @@ -217,23 +224,12 @@
>  }
>
>  int
> -afs_sync(mp, waitfor, cred, p)
> -     struct mount *mp;
> -     int waitfor;
> -     struct ucred *cred;
> -     struct prioc *p;
> +afs_sync(struct mount *mp, int waitfor, struct ucred *cred,
> THREAD_OR_PROC) {
>      return 0;
>  }
>
>  int
> -afs_sysctl()
> -{
> -    return EOPNOTSUPP;
> -}
> -
> -
> -int
>  afs_init(struct vfsconf *vfc)
>  {
>      return 0;
> @@ -247,7 +243,11 @@
>      afs_quotactl,
>      afs_statfs,
>      afs_sync,
> +#ifdef AFS_FBSD50_ENV
> +    NULL,
> +#else
>      afs_vget,
> +#endif
>      afs_fhtovp,
>  #ifdef AFS_FBSD50_ENV
>      vfs_stdcheckexp,
> @@ -255,7 +255,6 @@
>      afs_vptofh,
>      afs_init,
>  #ifdef AFS_FBSD50_ENV
> -    vfs_stduninit,
> +    vfs_stduninit
>  #endif
> -    afs_sysctl
>  };
> Index: src/afs/FBSD/osi_vm.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/FBSD/osi_vm.c,v
> retrieving revision 1.10
> diff -u -r1.10 osi_vm.c
> --- src/afs/FBSD/osi_vm.c	15 Jul 2003 23:14:20 -0000	1.10
> +++ src/afs/FBSD/osi_vm.c	8 Oct 2003 05:09:43 -0000
> @@ -32,6 +32,31 @@
>  #include <limits.h>
>  #include <float.h>
>
> +/*
> + * FreeBSD implementation notes:
> + * Most of these operations require us to frob vm_objects.  Most
> + * functions require that the object be locked (with VM_OBJECT_LOCK)
> + * on entry and leave it locked on exit.  In order to get the
> + * vm_object itself we call VOP_GETVOBJECT on the vnode; the
> + * locking protocol requires that we do so with the heavy vnode lock
> + * held and the vnode interlock unlocked, and it returns the same
> + * way.
> + *
> + * The locking protocol for vnodes is defined in
> + * kern/vnode_if.src and sys/vnode.h; the locking is still a work in
> + * progress, so some fields are (as of 5.1) still protected by Giant
> + * rather than an explicit lock.
> + */
> +
> +#define	lock_vnode(v)	vn_lock((v), LK_EXCLUSIVE | LK_RETRY, curthread)
> +#define unlock_vnode(v)	VOP_UNLOCK((v), 0, curthread)
> +
> +#ifndef AFS_FBSD50_ENV
> +/* need splvm() protection? */
> +#define	VM_OBJECT_LOCK(o)
> +#define VM_OBJECT_UNLOCK(o)
> +#endif
> +
>  /* Try to discard pages, in order to recycle a vcache entry.
>   *
>   * We also make some sanity checks:  ref count, open count, held locks.
> @@ -47,6 +72,8 @@
>   * therefore obsolescent.
>   *
>   * OSF/1 Locking:  VN_LOCK has been called.
> + * XXX - should FreeBSD have done this, too?  Certainly looks like it.
> + * Maybe better to just call vnode_pager_setsize()?
>   */
>  int
>  osi_VM_FlushVCache(struct vcache *avc, int *slept)
> @@ -65,8 +92,9 @@
>
>      AFS_GUNLOCK();
>      vp = AFSTOV(avc);
> -    simple_lock(&vp->v_interlock);
> +    lock_vnode(vp);
>      if (VOP_GETVOBJECT(vp, &obj) == 0) {
> +	VM_OBJECT_LOCK(obj);
>  	vm_object_page_remove(obj, 0, 0, FALSE);
>  #if 0
>  	if (obj->ref_count == 0) {
> @@ -76,8 +104,9 @@
>  	    SetAfsVnode(vp);
>  	}
>  #endif
> +	VM_OBJECT_UNLOCK(obj);
>      }
> -    simple_unlock(&vp->v_interlock);
> +    unlock_vnode(vp);
>      AFS_GLOCK();
>
>      return 0;
> @@ -99,25 +128,37 @@
>      AFS_GUNLOCK();
>      tries = 5;
>      vp = AFSTOV(avc);
> +
> +    /*
> +     * I don't understand this.  Why not just call vm_object_page_clean()
> +     * and be done with it?  I particularly don't understand why we're
> calling +     * vget() here.  Is there some reason to believe that the
> vnode might +     * be being recycled at this point?  I don't think there's
> any need for +     * this loop, either -- if we keep the vnode locked all
> the time, +     * that and the object lock will prevent any new pages from
> appearing. +     * The loop is what causes the race condition.  -GAW
> +     */
>      do {
>  	anyio = 0;
> -	simple_lock(&vp->v_interlock);
> +	lock_vnode(vp);
>  	if (VOP_GETVOBJECT(vp, &obj) == 0 && (obj->flags & OBJ_MIGHTBEDIRTY)) {
> +	    /* XXX - obj locking? */
> +	    unlock_vnode(vp);
>  #ifdef AFS_FBSD50_ENV
> -	    if (!vget(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY, curthread)) {
> +	    if (!vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread)) {
>  #else
> -	    if (!vget
> -		(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ,
> -		 curproc)) {
> +	    if (!vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) {
>  #endif
>  		if (VOP_GETVOBJECT(vp, &obj) == 0) {
> +		    VM_OBJECT_LOCK(obj);
>  		    vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
> +		    VM_OBJECT_UNLOCK(obj);
>  		    anyio = 1;
>  		}
>  		vput(vp);
>  	    }
>  	} else
> -	    simple_unlock(&vp->v_interlock);
> +	    unlock_vnode(vp);
>      } while (anyio && (--tries > 0));
>      AFS_GLOCK();
>      ObtainWriteLock(&avc->lock, 94);
> @@ -145,29 +186,41 @@
>      vp = AFSTOV(avc);
>      do {
>  	anyio = 0;
> -	simple_lock(&vp->v_interlock);
> +	lock_vnode(vp);
> +	/* See the comments above. */
>  	if (VOP_GETVOBJECT(vp, &obj) == 0 && (obj->flags & OBJ_MIGHTBEDIRTY)) {
> +	    /* XXX - obj locking */
> +	    unlock_vnode(vp);
>  #ifdef AFS_FBSD50_ENV
> -	    if (!vget(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY, curthread)) {
> +	    if (!vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread)) {
>  #else
> -	    if (!vget
> -		(vp, LK_INTERLOCK | LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ,
> -		 curproc)) {
> +	    if (!vget(vp, LK_EXCLUSIVE | LK_RETRY | LK_NOOBJ, curproc)) {
>  #endif
>  		if (VOP_GETVOBJECT(vp, &obj) == 0) {
> +		    VM_OBJECT_LOCK(obj);
> +		    /*
> +		     * Do we really want OBJPC_SYNC?  OBJPC_INVAL would be
> +		     * faster, if invalidation is really what we are being
> +		     * asked to do.  (It would make more sense, too, since
> +		     * otherwise this function is practically identical to
> +		     * osi_VM_StoreAllSegments().)  -GAW
> +		     */
>  		    vm_object_page_clean(obj, 0, 0, OBJPC_SYNC);
> +		    VM_OBJECT_UNLOCK(obj);
>  		    anyio = 1;
>  		}
>  		vput(vp);
>  	    }
>  	} else
> -	    simple_unlock(&vp->v_interlock);
> +	    unlock_vnode(vp);
>      } while (anyio && (--tries > 0));
> -    simple_lock(&vp->v_interlock);
> +    lock_vnode(vp);
>      if (VOP_GETVOBJECT(vp, &obj) == 0) {
> +	VM_OBJECT_LOCK(obj);
>  	vm_object_page_remove(obj, 0, 0, FALSE);
> +	VM_OBJECT_UNLOCK(obj);
>      }
> -    simple_unlock(&vp->v_interlock);
> +    unlock_vnode(vp);
>      /*vinvalbuf(AFSTOV(avc),0, NOCRED, curproc, 0,0); */
>      AFS_GLOCK();
>      ObtainWriteLock(&avc->lock, 59);
> @@ -184,11 +237,12 @@
>      struct vm_object *obj;
>
>      vp = AFSTOV(avc);
> -    simple_lock(&vp->v_interlock);
> +    ASSERT_VOP_LOCKED(vp, __func__);
>      if (VOP_GETVOBJECT(vp, &obj) == 0) {
> +	VM_OBJECT_LOCK(obj);
>  	vm_object_page_remove(obj, 0, 0, FALSE);
> +	VM_OBJECT_UNLOCK(obj);
>      }
> -    simple_unlock(&vp->v_interlock);
>      /*vinvalbuf(AFSTOV(avc),0, NOCRED, curproc, 0,0); */
>  }
>
> Index: src/afs/FBSD/osi_vnodeops.c
> ===================================================================
> RCS file: /cvs/openafs/src/afs/FBSD/osi_vnodeops.c,v
> retrieving revision 1.16
> diff -u -r1.16 osi_vnodeops.c
> --- src/afs/FBSD/osi_vnodeops.c	27 Aug 2003 21:43:17 -0000	1.16
> +++ src/afs/FBSD/osi_vnodeops.c	8 Oct 2003 05:09:44 -0000
> @@ -1,3 +1,49 @@
> +/*
> + * A large chunk of this file appears to be copied directly from
> + * sys/nfsclient/nfs_bio.c, which has the following license:
> + */
> +/*
> + * Copyright (c) 1989, 1993
> + *	The Regents of the University of California.  All rights reserved.
> + *
> + * This code is derived from software contributed to Berkeley by
> + * Rick Macklem at The University of Guelph.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + * 3. All advertising materials mentioning features or use of this
> software + *    must display the following acknowledgement:
> + *	This product includes software developed by the University of
> + *	California, Berkeley and its contributors.
> + * 4. Neither the name of the University nor the names of its contributors
> + *    may be used to endorse or promote products derived from this
> software + *    without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
> PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
> BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
> CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
> SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
> BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
> WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
> OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF
> ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE.
> + *
> + *	@(#)nfs_bio.c	8.9 (Berkeley) 3/30/95
> + */
> +/*
> + * Pursuant to a statement of U.C. Berkeley dated 1999-07-22, this license
> + * is amended to drop clause (3) above.
> + */
> +
>  #include <afsconfig.h>
>  #include <afs/param.h>
>
> @@ -9,6 +55,7 @@
>  #include <afs/afs_stats.h>	/* statistics */
>  #include <sys/malloc.h>
>  #include <sys/namei.h>
> +#include <sys/unistd.h>
>  #ifndef AFS_FBSD50_ENV
>  #include <vm/vm_zone.h>
>  #endif
> @@ -31,6 +78,7 @@
>  int afs_vop_getpages(struct vop_getpages_args *);
>  int afs_vop_putpages(struct vop_putpages_args *);
>  int afs_vop_ioctl(struct vop_ioctl_args *);
> +static int afs_vop_pathconf(struct vop_pathconf_args *);
>  int afs_vop_poll(struct vop_poll_args *);
>  #ifndef AFS_FBSD50_ENV
>  int afs_vop_mmap(struct vop_mmap_args *);
> @@ -59,7 +107,7 @@
>  /* 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_default_desc, (vop_t *) vop_defaultop},
>      {&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 */
> @@ -76,10 +124,8 @@
>      {&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 */
> @@ -87,6 +133,7 @@
>      {&vop_mmap_desc, (vop_t *) afs_vop_mmap},	/* mmap */
>  #endif
>      {&vop_open_desc, (vop_t *) afs_vop_open},	/* open */
> +    {&vop_pathconf_desc, (vop_t *) afs_vop_pathconf},	/* pathconf */
>      {&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 */
> @@ -99,7 +146,6 @@
>      {&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 */
> @@ -122,7 +168,98 @@
>  #define a_p a_td
>  #endif
>
> +/*
> + * Mosty copied from sys/ufs/ufs/ufs_vnops.c:ufs_pathconf().
> + * We should know the correct answers to these questions with
> + * respect to the AFS protocol (which may differ from the UFS
> + * values) but for the moment this will do.
> + */
> +static int
> +afs_vop_pathconf(struct vop_pathconf_args *ap)
> +{
> +	int error;
>
> +	error = 0;
> +	switch (ap->a_name) {
> +	case _PC_LINK_MAX:
> +		*ap->a_retval = LINK_MAX;
> +		break;
> +	case _PC_NAME_MAX:
> +		*ap->a_retval = NAME_MAX;
> +		break;
> +	case _PC_PATH_MAX:
> +		*ap->a_retval = PATH_MAX;
> +		break;
> +	case _PC_PIPE_BUF:
> +		*ap->a_retval = PIPE_BUF;
> +		break;
> +	case _PC_CHOWN_RESTRICTED:
> +		*ap->a_retval = 1;
> +		break;
> +	case _PC_NO_TRUNC:
> +		*ap->a_retval = 1;
> +		break;
> +#ifdef _PC_ACL_EXTENDED
> +	case _PC_ACL_EXTENDED:
> +		*ap->a_retval = 0;
> +		break;
> +	case _PC_ACL_PATH_MAX:
> +		*ap->a_retval = 3;
> +		break;
> +#endif
> +#ifdef _PC_MAC_PRESENT
> +	case _PC_MAC_PRESENT:
> +		*ap->a_retval = 0;
> +		break;
> +#endif
> +#ifdef _PC_ASYNC_IO
> +	case _PC_ASYNC_IO:
> +		/* _PC_ASYNC_IO should have been handled by upper layers. */
> +		KASSERT(0, ("_PC_ASYNC_IO should not get here"));
> +		error = EINVAL;
> +		break;
> +	case _PC_PRIO_IO:
> +		*ap->a_retval = 0;
> +		break;
> +	case _PC_SYNC_IO:
> +		*ap->a_retval = 0;
> +		break;
> +#endif
> +#ifdef _PC_ALLOC_SIZE_MIN
> +	case _PC_ALLOC_SIZE_MIN:
> +		*ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_bsize;
> +		break;
> +#endif
> +#ifdef _PC_FILESIZEBITS
> +	case _PC_FILESIZEBITS:
> +		*ap->a_retval = 32; /* XXX */
> +		break;
> +#endif
> +#ifdef _PC_REC_INCR_XFER_SIZE
> +	case _PC_REC_INCR_XFER_SIZE:
> +		*ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
> +		break;
> +	case _PC_REC_MAX_XFER_SIZE:
> +		*ap->a_retval = -1; /* means ``unlimited'' */
> +		break;
> +	case _PC_REC_MIN_XFER_SIZE:
> +		*ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
> +		break;
> +	case _PC_REC_XFER_ALIGN:
> +		*ap->a_retval = PAGE_SIZE;
> +		break;
> +#endif
> +#ifdef _PC_SYMLINK_MAX
> +	case _PC_SYMLINK_MAX:
> +		*ap->a_retval = MAXPATHLEN;
> +		break;
> +#endif
> +	default:
> +		error = EINVAL;
> +		break;
> +	}
> +	return (error);
> +}
>
>  int
>  afs_vop_lookup(ap)
> @@ -397,15 +534,16 @@
>      return code;
>  }
>
> +/* struct vop_getpages_args {
> + *	struct vnode *a_vp;
> + *	vm_page_t *a_m;
> + *	int a_count;
> + *	int a_reqpage;
> + *	vm_oofset_t a_offset;
> + * };
> + */
>  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;
> +afs_vop_getpages(struct vop_getpages_args *ap)
>  {
>      int code;
>      int i, nextoff, size, toff, npages;
> @@ -413,9 +551,16 @@
>      struct iovec iov;
>      struct buf *bp;
>      vm_offset_t kva;
> -    struct vcache *avc = VTOAFS(ap->a_vp);
> +    vm_object_t object;
> +    struct vnode *vp;
> +    struct vcache *avc;
>
> -    if (avc->v.v_object == NULL) {
> +#ifdef AFS_FBSD50_ENV
> +    GIANT_REQUIRED;
> +#endif
> +    vp = ap->a_vp;
> +    avc = VTOAFS(vp);
> +    if ((object = vp->v_object) == NULL) {
>  	printf("afs_getpages: called with non-merged cache vnode??\n");
>  	return VM_PAGER_ERROR;
>      }
> @@ -429,6 +574,10 @@
>      {
>  	vm_page_t m = ap->a_m[ap->a_reqpage];
>
> +#ifdef AFS_FBSD50_ENV
> +	VM_OBJECT_LOCK(object);
> +	vm_page_lock_queues();
> +#endif
>  	if (m->valid != 0) {
>  	    /* handled by vm_fault now        */
>  	    /* vm_page_zero_invalid(m, TRUE); */
> @@ -436,12 +585,24 @@
>  		if (i != ap->a_reqpage)
>  		    vm_page_free(ap->a_m[i]);
>  	    }
> +#ifdef AFS_FBSD50_ENV
> +	    vm_page_unlock_queues();
> +	    VM_OBJECT_UNLOCK(object);
> +#endif
>  	    return (0);
>  	}
> +#ifdef AFS_FBSD50_ENV
> +	vm_page_unlock_queues();
> +	VM_OBJECT_UNLOCK(object);
> +#endif
>      }
>      bp = getpbuf(&afs_pbuf_freecnt);
> +
>      kva = (vm_offset_t) bp->b_data;
>      pmap_qenter(kva, ap->a_m, npages);
> +    cnt.v_vnodein++;
> +    cnt.v_vnodepgsin += npages;
> +
>      iov.iov_base = (caddr_t) kva;
>      iov.iov_len = ap->a_count;
>      uio.uio_iov = &iov;
> @@ -455,6 +616,7 @@
>  #else
>      uio.uio_procp = curproc;
>  #endif
> +
>      AFS_GLOCK();
>      afs_BozonLock(&avc->pvnLock, avc);
>      osi_FlushPages(avc, osi_curcred());	/* hold bozon lock, but not basic
> vnode lock */ @@ -464,14 +626,28 @@
>      pmap_qremove(kva, npages);
>
>      relpbuf(bp, &afs_pbuf_freecnt);
> +
>      if (code && (uio.uio_resid == ap->a_count)) {
> +#ifdef AFS_FBSD50_ENV
> +	VM_OBJECT_LOCK(object);
> +	vm_page_lock_queues();
> +#endif
>  	for (i = 0; i < npages; ++i) {
>  	    if (i != ap->a_reqpage)
>  		vm_page_free(ap->a_m[i]);
>  	}
> +#ifdef AFS_FBSD50_ENV
> +	vm_page_unlock_queues();
> +	VM_OBJECT_UNLOCK(object);
> +#endif
>  	return VM_PAGER_ERROR;
>      }
> +
>      size = ap->a_count - uio.uio_resid;
> +#ifdef AFS_FBSD50_ENV
> +    VM_OBJECT_LOCK(object);
> +    vm_page_lock_queues();
> +#endif
>      for (i = 0, toff = 0; i < npages; i++, toff = nextoff) {
>  	vm_page_t m;
>  	nextoff = toff + PAGE_SIZE;
> @@ -519,6 +695,10 @@
>  	    }
>  	}
>      }
> +#ifdef AFS_FBSD50_ENV
> +    vm_page_unlock_queues();
> +    VM_OBJECT_UNLOCK(object);
> +#endif
>      return 0;
>  }
>
> @@ -543,16 +723,22 @@
>      return code;
>  }
>
> +/*-
> + * 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;
> + * };
> + */
> +/*
> + * All of the pages passed to us in ap->a_m[] are already marked as busy,
> + * so there is no additional locking required to set their flags.  -GAW
> + */
>  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;
> +afs_vop_putpages(struct vop_putpages_args *ap)
>  {
>      int code;
>      int i, size, npages, sync;
> @@ -560,22 +746,34 @@
>      struct iovec iov;
>      struct buf *bp;
>      vm_offset_t kva;
> -    struct vcache *avc = VTOAFS(ap->a_vp);
> +    struct vnode *vp;
> +    struct vcache *avc;
> +
> +#ifdef AFS_FBSD50_ENV
> +    GIANT_REQUIRED;
> +#endif
>
> -    if (avc->v.v_object == NULL) {
> +    vp = ap->a_vp;
> +    avc = VTOAFS(vp);
> +    /* Perhaps these two checks should just be KASSERTs instead... */
> +    if (vp->v_object == NULL) {
>  	printf("afs_putpages: called with non-merged cache vnode??\n");
> -	return VM_PAGER_ERROR;
> +	return VM_PAGER_ERROR;	/* XXX I think this is insufficient */
>      }
>      if (vType(avc) != VREG) {
>  	printf("afs_putpages: not VREG");
> -	return VM_PAGER_ERROR;
> +	return VM_PAGER_ERROR;	/* XXX I think this is insufficient */
>      }
>      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);
> +    cnt.v_vnodeout++;
> +    cnt.v_vnodepgsout += ap->a_count;
> +
>      iov.iov_base = (caddr_t) kva;
>      iov.iov_len = ap->a_count;
>      uio.uio_iov = &iov;
> @@ -600,16 +798,16 @@
>      code = afs_write(avc, &uio, sync, osi_curcred(), 0);
>      afs_BozonUnlock(&avc->pvnLock, avc);
>      AFS_GUNLOCK();
> -    pmap_qremove(kva, npages);
>
> +    pmap_qremove(kva, npages);
>      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;
> +	    vm_page_undirty(ap->a_m[i]);
>  	}
> -	return VM_PAGER_ERROR;
>      }
>      return ap->a_rtvals[0];
>  }
> @@ -933,26 +1131,44 @@
>      return error;
>  }
>
> +/* struct vop_symlink_args {
> + *	struct vnode *a_dvp;
> + *	struct vnode **a_vpp;
> + *	struct componentname *a_cnp;
> + *	struct vattr *a_vap;
> + *	char *a_target;
> + * };
> + */
>  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;
> +afs_vop_symlink(struct vop_symlink_args *ap)
>  {
> -    register struct vnode *dvp = ap->a_dvp;
> -    int error = 0;
> -    /* NFS ignores a_vpp; so do we. */
> +    struct vnode *dvp;
> +    struct vnode *newvp;
> +    struct vcache *vcp;
> +    int error;
> +
> +    dvp = ap->a_dvp;
> +    newvp = NULL;
> +    error = 0;
>
>      GETNAME();
>      AFS_GLOCK();
>      error =
>  	afs_symlink(VTOAFS(dvp), name, ap->a_vap, ap->a_target, cnp->cn_cred);
> +    if (error == 0) {
> +	error = afs_lookup(VTOAFS(dvp), name, &vcp, cnp->cn_cred);
> +	if (error == 0) {
> +	    newvp = AFSTOV(vcp);
> +#ifdef AFS_FBSD50_ENV
> +	    vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_thread);
> +#else
> +	    vn_lock(newvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_proc);
> +#endif
> +	}
> +    }
>      AFS_GUNLOCK();
>      DROPNAME();
> +    *(ap->a_vpp) = newvp;
>      return error;
>  }
>
> @@ -1043,69 +1259,36 @@
>      return 0;
>  }
>
> +/*
> + * struct vop_reclaim_args {
> + *	struct vnode *a_vp;
> + * };
> + */
>  int
> -afs_vop_reclaim(ap)
> -     struct vop_reclaim_args	/* {
> -				 * struct vnode *a_vp;
> -				 * } */ *ap;
> -{
> -#ifdef AFS_DO_FLUSH_IN_RECLAIM
> -    int error, sl;
> -#endif
> -    register struct vnode *vp = ap->a_vp;
> -
> -    cache_purge(vp);		/* just in case... */
> -
> -#ifdef AFS_DO_FLUSH_IN_RECLAIM
> -    AFS_GLOCK();
> -    error = afs_FlushVCache(VTOAFS(vp), &sl);	/* tosses our stuff from
> vnode */ -    AFS_GUNLOCK();
> -    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
> -}
> -
> -int
> -afs_vop_lock(ap)
> -     struct vop_lock_args	/* {
> -				 * struct vnode *a_vp;
> -				 * } */ *ap;
> -{
> -    register struct vnode *vp = ap->a_vp;
> -    register struct vcache *avc = VTOAFS(vp);
> -
> -#ifdef AFS_FBSD50_ENV
> -    if (!strcmp(vp->v_tag, "none"))
> -#else
> -    if (vp->v_tag == VT_NON)
> -#endif
> -	return (ENOENT);
> -    return (lockmgr(&avc->rwlock, ap->a_flags, &vp->v_interlock,
> ap->a_p)); -}
> -
> -int
> -afs_vop_unlock(ap)
> -     struct vop_unlock_args	/* {
> -				 * struct vnode *a_vp;
> -				 * } */ *ap;
> +afs_vop_reclaim(struct vop_reclaim_args *ap)
>  {
> +    /* copied from ../OBSD/osi_vnodeops.c:afs_nbsd_reclaim() */
> +    int code, slept;
>      struct vnode *vp = ap->a_vp;
>      struct vcache *avc = VTOAFS(vp);
> -    return (lockmgr
> -	    (&avc->rwlock, ap->a_flags | LK_RELEASE, &vp->v_interlock,
> -	     ap->a_p));
> +    int haveGlock = ISAFS_GLOCK();
> +    int haveVlock = CheckLock(&afs_xvcache);
>
> +    if (!haveGlock)
> +	AFS_GLOCK();
> +    if (!haveVlock)
> +	ObtainWriteLock(&afs_xvcache, 901);
> +#ifndef AFS_DISCON_ENV
> +    code = afs_FlushVCache(avc, &slept);	/* tosses our stuff from vnode */
> +#else
> +    /* reclaim the vnode and the in-memory vcache, but keep the on-disk
> vcache */ +    code = afs_FlushVS(avc);
> +#endif
> +    if (!haveVlock)
> +	ReleaseWriteLock(&afs_xvcache);
> +    if (!haveGlock)
> +	AFS_GUNLOCK();
> +    return code;
>  }
>
>  int
> @@ -1173,16 +1356,6 @@
>  	   (s & CVFlushed) ? " flush in progress" : "");
>      printf("\n");
>      return 0;
> -}
> -
> -int
> -afs_vop_islocked(ap)
> -     struct vop_islocked_args	/* {
> -				 * struct vnode *a_vp;
> -				 * } */ *ap;
> -{
> -    struct vcache *vc = VTOAFS(ap->a_vp);
> -    return lockstatus(&vc->rwlock, ap->a_p);
>  }
>
>  /*
> Index: src/cf/osconf.m4
> ===================================================================
> RCS file: /cvs/openafs/src/cf/osconf.m4,v
> retrieving revision 1.39
> diff -u -r1.39 osconf.m4
> --- src/cf/osconf.m4	1 Jul 2003 19:30:30 -0000	1.39
> +++ src/cf/osconf.m4	8 Oct 2003 05:09:47 -0000
> @@ -191,7 +191,7 @@
>  		SHLIB_LDFLAGS="-shared -Xlinker -x"
>  		TXLIBS="-lncurses"
>  		XCFLAGS="-O2 -pipe"
> -		XLIBS="${LIB_AFSDB} -lcompat"
> +		XLIBS="${LIB_AFSDB}"
>  		YACC="byacc"
>  		;;
>
> @@ -203,7 +203,7 @@
>  		SHLIB_LDFLAGS="-shared -Xlinker -x"
>  		TXLIBS="-lncurses"
>  		XCFLAGS="-O2 -pipe"
> -		XLIBS="${LIB_AFSDB} -lcompat"
> +		XLIBS="${LIB_AFSDB}"
>  		YACC="byacc"
>  		;;
>
> Index: src/config/param.i386_fbsd_42.h
> ===================================================================
> RCS file: /cvs/openafs/src/config/param.i386_fbsd_42.h,v
> retrieving revision 1.9
> diff -u -r1.9 param.i386_fbsd_42.h
> --- src/config/param.i386_fbsd_42.h	15 Jul 2003 23:14:55 -0000	1.9
> +++ src/config/param.i386_fbsd_42.h	8 Oct 2003 05:09:48 -0000
> @@ -79,8 +79,10 @@
>  #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	AFS_KALLOC(x)	osi_fbsd_alloc((x), 1)
> +#undef	AFS_KALLOC_NOSLEEP
> +#define	AFS_KALLOC_NOSLEEP(x)	osi_fbsd_alloc((x), 0)
> +#define	AFS_KFREE(x,y)	osi_fbsd_free((x))
>  #define	v_count		v_usecount
>  #define v_vfsp		v_mount
>  #define vfs_bsize	mnt_stat.f_bsize
> Index: src/config/param.i386_fbsd_43.h
> ===================================================================
> RCS file: /cvs/openafs/src/config/param.i386_fbsd_43.h,v
> retrieving revision 1.6
> diff -u -r1.6 param.i386_fbsd_43.h
> --- src/config/param.i386_fbsd_43.h	15 Jul 2003 23:14:55 -0000	1.6
> +++ src/config/param.i386_fbsd_43.h	8 Oct 2003 05:09:48 -0000
> @@ -81,8 +81,10 @@
>  #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 AFS_KALLOC(x)   osi_fbsd_alloc((x), 1)
> +#undef	AFS_KALLOC_NOSLEEP
> +#define	AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
> +#define AFS_KFREE(x,y)  osi_fbsd_free((x))
>  #define	v_count		v_usecount
>  #define v_vfsp		v_mount
>  #define vfs_bsize	mnt_stat.f_bsize
> Index: src/config/param.i386_fbsd_44.h
> ===================================================================
> RCS file: /cvs/openafs/src/config/param.i386_fbsd_44.h,v
> retrieving revision 1.6
> diff -u -r1.6 param.i386_fbsd_44.h
> --- src/config/param.i386_fbsd_44.h	15 Jul 2003 23:14:55 -0000	1.6
> +++ src/config/param.i386_fbsd_44.h	8 Oct 2003 05:09:48 -0000
> @@ -83,8 +83,10 @@
>  #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 AFS_KALLOC(x)   osi_fbsd_alloc((x), 1)
> +#undef	AFS_KALLOC_NOSLEEP
> +#define	AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
> +#define AFS_KFREE(x,y)  osi_fbsd_free((x))
>  #define	v_count		v_usecount
>  #define v_vfsp		v_mount
>  #define vfs_bsize	mnt_stat.f_bsize
> Index: src/config/param.i386_fbsd_45.h
> ===================================================================
> RCS file: /cvs/openafs/src/config/param.i386_fbsd_45.h,v
> retrieving revision 1.7
> diff -u -r1.7 param.i386_fbsd_45.h
> --- src/config/param.i386_fbsd_45.h	15 Jul 2003 23:14:55 -0000	1.7
> +++ src/config/param.i386_fbsd_45.h	8 Oct 2003 05:09:48 -0000
> @@ -84,8 +84,10 @@
>  #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 AFS_KALLOC(x)   osi_fbsd_alloc((x), 1)
> +#undef	AFS_KALLOC_NOSLEEP
> +#define	AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
> +#define AFS_KFREE(x,y)  osi_fbsd_free((x))
>  #define	v_count		v_usecount
>  #define v_vfsp		v_mount
>  #define vfs_bsize	mnt_stat.f_bsize
> Index: src/config/param.i386_fbsd_46.h
> ===================================================================
> RCS file: /cvs/openafs/src/config/param.i386_fbsd_46.h,v
> retrieving revision 1.6
> diff -u -r1.6 param.i386_fbsd_46.h
> --- src/config/param.i386_fbsd_46.h	15 Jul 2003 23:14:55 -0000	1.6
> +++ src/config/param.i386_fbsd_46.h	8 Oct 2003 05:09:48 -0000
> @@ -85,8 +85,10 @@
>  #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 AFS_KALLOC(x)   osi_fbsd_alloc((x), 1)
> +#undef	AFS_KALLOC_NOSLEEP
> +#define	AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
> +#define AFS_KFREE(x,y)  osi_fbsd_free((x))
>  #define	v_count		v_usecount
>  #define v_vfsp		v_mount
>  #define vfs_bsize	mnt_stat.f_bsize
> Index: src/config/param.i386_fbsd_47.h
> ===================================================================
> RCS file: /cvs/openafs/src/config/param.i386_fbsd_47.h,v
> retrieving revision 1.4
> diff -u -r1.4 param.i386_fbsd_47.h
> --- src/config/param.i386_fbsd_47.h	15 Jul 2003 23:14:55 -0000	1.4
> +++ src/config/param.i386_fbsd_47.h	8 Oct 2003 05:09:48 -0000
> @@ -87,8 +87,10 @@
>  #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 AFS_KALLOC(x)   osi_fbsd_alloc((x), 1)
> +#undef	AFS_KALLOC_NOSLEEP
> +#define	AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
> +#define AFS_KFREE(x,y)  osi_fbsd_free((x))
>  #define	v_count		v_usecount
>  #define v_vfsp		v_mount
>  #define vfs_bsize	mnt_stat.f_bsize
> Index: src/config/param.i386_fbsd_50.h
> ===================================================================
> RCS file: /cvs/openafs/src/config/param.i386_fbsd_50.h,v
> retrieving revision 1.6
> diff -u -r1.6 param.i386_fbsd_50.h
> --- src/config/param.i386_fbsd_50.h	15 Jul 2003 23:14:55 -0000	1.6
> +++ src/config/param.i386_fbsd_50.h	8 Oct 2003 05:09:49 -0000
> @@ -88,8 +88,10 @@
>  #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 AFS_KALLOC(x)   osi_fbsd_alloc((x), 1)
> +#undef	AFS_KALLOC_NOSLEEP
> +#define	AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
> +#define AFS_KFREE(x,y)  osi_fbsd_free((x))
>  #define	v_count		v_usecount
>  #define v_vfsp		v_mount
>  #define vfs_bsize	mnt_stat.f_bsize
> Index: src/config/param.i386_fbsd_51.h
> ===================================================================
> RCS file: /cvs/openafs/src/config/param.i386_fbsd_51.h,v
> retrieving revision 1.1
> diff -u -r1.1 param.i386_fbsd_51.h
> --- src/config/param.i386_fbsd_51.h	17 Jul 2003 16:00:56 -0000	1.1
> +++ src/config/param.i386_fbsd_51.h	8 Oct 2003 05:09:49 -0000
> @@ -79,7 +79,7 @@
>  #ifdef _KERNEL
>  #define AFS_GLOBAL_SUNLOCK        1
>  #define	AFS_VFS34	1	/* What is VFS34??? */
> -#define	AFS_SHORTGID	1	/* are group id's short? */
> +#define	AFS_SHORTGID	0	/* are group id's short? */
>  #define	afsio_iov	uio_iov
>  #define	afsio_iovcnt	uio_iovcnt
>  #define	afsio_offset	uio_offset
> @@ -89,8 +89,10 @@
>  #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 AFS_KALLOC(x)   osi_fbsd_alloc((x), 1)
> +#undef	AFS_KALLOC_NOSLEEP
> +#define	AFS_KALLOC_NOSLEEP(x) osi_fbsd_alloc((x), 0)
> +#define AFS_KFREE(x,y)  osi_fbsd_free((x))
>  #define	v_count		v_usecount
>  #define v_vfsp		v_mount
>  #define vfs_bsize	mnt_stat.f_bsize
> @@ -169,7 +171,7 @@
>  #define SYS_NAME_ID	SYS_NAME_ID_i386_fbsd_51
>  #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_HAVE_STATVFS    1	/* System doesn't support statvfs */
>  #define AFS_VM_RDWR_ENV	    1	/* read/write implemented via VM */
>
>  #define	afsio_iov	uio_iov
> Index: src/libafs/MakefileProto.FBSD.in
> ===================================================================
> RCS file: /cvs/openafs/src/libafs/MakefileProto.FBSD.in,v
> retrieving revision 1.22
> diff -u -r1.22 MakefileProto.FBSD.in
> --- src/libafs/MakefileProto.FBSD.in	1 Jul 2003 18:06:40 -0000	1.22
> +++ src/libafs/MakefileProto.FBSD.in	8 Oct 2003 05:09:51 -0000
> @@ -34,9 +34,11 @@
>  <i386_fbsd_42 i386_fbsd_43 i386_fbsd_44 i386_fbsd_45 i386_fbsd_46
> i386_fbsd_47> -fformat-extensions
>  <all -i386_fbsd_42 -i386_fbsd_43 -i386_fbsd_44 -i386_fbsd_45 -i386_fbsd_46
> -i386_fbsd_47> -	-mno-align-long-strings -fformat-extensions -fno-common
> -ffreestanding +	-mno-align-long-strings -fformat-extensions -fno-common
> -ffreestanding \ +	-I/sys/i386/compile/AFS -include opt_global.h
> -fno-strict-aliasing +
>  <all>
> -DBUG = -O2
> +DBUG = -O -g
>  DEFINES= -DAFSDEBUG -DKERNEL -DAFS -DVICE -DNFS -DUFS -DINET -DQUOTA
> -DGETMOUNT OPTF=${OPT}
>  OPTF2=${OPT2}
> Index: src/libuafs/MakefileProto.FBSD.in
> ===================================================================
> RCS file: /cvs/openafs/src/libuafs/MakefileProto.FBSD.in,v
> retrieving revision 1.9
> diff -u -r1.9 MakefileProto.FBSD.in
> --- src/libuafs/MakefileProto.FBSD.in	10 Mar 2003 01:59:40 -0000	1.9
> +++ src/libuafs/MakefileProto.FBSD.in	8 Oct 2003 05:09:51 -0000
> @@ -10,16 +10,16 @@
>
>
>  # System specific build commands and flags
> -CC = gcc
> +CC = @CC@
>  DEFINES= -D_REENTRANT -DKERNEL -DUKERNEL
>  KOPTS=
>  CFLAGS=-I. -I.. -I${TOP_OBJDIR}/src/config ${FSINCLUDES} $(DEFINES)
> $(KOPTS) ${DBUG} OPTF=-O
>  # WEBOPTS = -I../nsapi -DNETSCAPE_NSAPI -DNET_SSL -DXP_UNIX -DMCC_HTTPD
>
> -TEST_CFLAGS=-pthread -D_REENTRANT -DAFS_PTHREAD_ENV -DAFS_FBSD40_ENV
> +TEST_CFLAGS=-D_REENTRANT -DAFS_PTHREAD_ENV -DAFS_FBSD40_ENV
>  TEST_LDFLAGS=
> -TEST_LIBS=
> +TEST_LIBS=-lc_r
>
>  LIBUAFS = libuafs.a
>  LIBJUAFS = libjuafs.a
> Index: src/rx/rx_kcommon.c
> ===================================================================
> RCS file: /cvs/openafs/src/rx/rx_kcommon.c,v
> retrieving revision 1.37
> diff -u -r1.37 rx_kcommon.c
> --- src/rx/rx_kcommon.c	27 Aug 2003 21:43:19 -0000	1.37
> +++ src/rx/rx_kcommon.c	8 Oct 2003 05:09:53 -0000
> @@ -776,6 +776,8 @@
>  #if (defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)) &&
> defined(KERNEL_FUNNEL) thread_funnel_switch(KERNEL_FUNNEL, NETWORK_FUNNEL);
>  #endif
> +    AFS_ASSERT_GLOCK();
> +    AFS_GUNLOCK();
>  #if	defined(AFS_HPUX102_ENV)
>  #if     defined(AFS_HPUX110_ENV)
>      /* blocking socket */
> @@ -796,6 +798,7 @@
>      if (code)
>  	goto bad;
>
> +    memset(&myaddr, 0, sizeof myaddr);
>      myaddr.sin_family = AF_INET;
>      myaddr.sin_port = aport;
>      myaddr.sin_addr.s_addr = 0;
> @@ -841,6 +844,7 @@
>      if (code) {
>  	printf("sobind fails (%d)\n", (int)code);
>  	soclose(newSocket);
> +        AFS_GLOCK();
>  	goto bad;
>      }
>  #else /* defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) */
> @@ -875,12 +879,14 @@
>  #endif /* else AFS_DARWIN_ENV */
>  #endif /* else AFS_HPUX110_ENV */
>
> +    AFS_GLOCK();
>  #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
>      thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
>  #endif
>      return (struct osi_socket *)newSocket;
>
>    bad:
> +    AFS_GLOCK();
>  #if defined(AFS_DARWIN_ENV) && defined(KERNEL_FUNNEL)
>      thread_funnel_switch(NETWORK_FUNNEL, KERNEL_FUNNEL);
>  #endif
> Index: src/rx/rx_prototypes.h
> ===================================================================
> RCS file: /cvs/openafs/src/rx/rx_prototypes.h,v
> retrieving revision 1.12
> diff -u -r1.12 rx_prototypes.h
> --- src/rx/rx_prototypes.h	15 Jul 2003 23:16:10 -0000	1.12
> +++ src/rx/rx_prototypes.h	8 Oct 2003 05:09:53 -0000
> @@ -561,9 +561,15 @@
>
>  /* EXTERNAL PROTOTYPES - include here cause it causes too many issues to
>     include the afs_prototypes.h file - just make sure they match */
> +#ifndef afs_osi_Alloc
>  extern void *afs_osi_Alloc(size_t x);
> +#endif
> +#ifndef afs_osi_Alloc_NoSleep
>  extern void *afs_osi_Alloc_NoSleep(size_t x);
> +#endif
> +#ifndef afs_osi_Free
>  extern void afs_osi_Free(void *x, size_t asize);
> +#endif
>  #ifndef afs_osi_Wakeup
>  extern int afs_osi_Wakeup(void *event);
>  #endif
> Index: src/rx/xdr.h
> ===================================================================
> RCS file: /cvs/openafs/src/rx/xdr.h,v
> retrieving revision 1.10
> diff -u -r1.10 xdr.h
> --- src/rx/xdr.h	15 Jul 2003 23:16:12 -0000	1.10
> +++ src/rx/xdr.h	8 Oct 2003 05:09:54 -0000
> @@ -96,7 +96,9 @@
>
>  /* keep here for now, 64 bit issues */
>  extern void *afs_osi_Alloc(size_t x);
> +#ifndef afs_osi_Alloc_NoSleep
>  extern void *afs_osi_Alloc_NoSleep(size_t x);
> +#endif
>  extern void afs_osi_Free(void *x, size_t asize);
>
>  #endif
> Index: src/rx/FBSD/rx_knet.c
> ===================================================================
> RCS file: /cvs/openafs/src/rx/FBSD/rx_knet.c,v
> retrieving revision 1.13
> diff -u -r1.13 rx_knet.c
> --- src/rx/FBSD/rx_knet.c	15 Jul 2003 23:16:18 -0000	1.13
> +++ src/rx/FBSD/rx_knet.c	8 Oct 2003 05:09:56 -0000
> @@ -83,10 +83,20 @@
>  {
>      struct proc *p;
>
> +    /*
> +     * Have to drop global lock to safely do this.
> +     * soclose() is currently protected by Giant,
> +     * but pfind and psignal are MPSAFE.
> +     */
> +    AFS_GUNLOCK();
>      soclose(rx_socket);
>      p = pfind(rxk_ListenerPid);
>      if (p)
>  	psignal(p, SIGUSR1);
> +#ifdef AFS_FBSD50_ENV
> +    PROC_UNLOCK(p);
> +#endif
> +    AFS_GLOCK();
>  }
>
>  int
> Index: src/vlserver/vlprocs.c
> ===================================================================
> RCS file: /cvs/openafs/src/vlserver/vlprocs.c,v
> retrieving revision 1.10
> diff -u -r1.10 vlprocs.c
> --- src/vlserver/vlprocs.c	15 Jul 2003 23:17:34 -0000	1.10
> +++ src/vlserver/vlprocs.c	8 Oct 2003 05:10:02 -0000
> @@ -38,6 +38,12 @@
>  #ifndef AFS_NT40_ENV
>  #include <unistd.h>
>  #endif
> +#ifdef AFS_FBSD_ENV		/* XXX for now */
> +#define HAVE_REGEX_H
> +#endif
> +#ifdef HAVE_REGEX_H		/* use POSIX regexp library */
> +#include <regex.h>
> +#endif
>
>  extern int smallMem;
>  extern extent_mod;
> @@ -1376,6 +1382,10 @@
>      int pollcount = 0;
>      int namematchRWBK, namematchRO, thismatch, matchtype;
>      char volumename[VL_MAXNAMELEN];
> +#ifdef HAVE_REGEX_H
> +    regex_t re;
> +    int need_regfree = 0;
> +#endif
>
>      COUNT_REQ(VLLISTATTRIBUTESN2);
>      vldbentries->nbulkentries_val = 0;
> @@ -1433,11 +1443,19 @@
>  	findflag = ((attributes->Mask & VLLIST_FLAG) ? 1 : 0);
>  	if (name && (strcmp(name, ".*") != 0) && (strcmp(name, "") != 0)) {
>  	    sprintf(volumename, "^%s$", name);
> +#ifdef HAVE_REGEX_H
> +	    if (regcomp(&re, volumename, REG_BASIC | REG_NOSUB) != 0) {
> +		errorcode = VL_BADNAME;
> +		goto done;
> +	    }
> +	    need_regfree = 1;
> +#else
>  	    t = (char *)re_comp(volumename);
>  	    if (t) {
>  		errorcode = VL_BADNAME;
>  		goto done;
>  	    }
> +#endif
>  	    findname = 1;
>  	}
>
> @@ -1468,9 +1486,15 @@
>  		    if (tentry.flags & VLF_RWEXISTS) {
>  			if (findname) {
>  			    sprintf(volumename, "%s", tentry.name);
> +#ifdef HAVE_REGEX_H
> +			    if (regexec(&re, volumename, 0, NULL, 0) == 0) {
> +				thismatch = VLSF_RWVOL;
> +			    }
> +#else
>  			    if (re_exec(volumename)) {
>  				thismatch = VLSF_RWVOL;
>  			    }
> +#endif
>  			} else {
>  			    thismatch = VLSF_RWVOL;
>  			}
> @@ -1480,9 +1504,15 @@
>  		    if (!thismatch && (tentry.flags & VLF_BACKEXISTS)) {
>  			if (findname) {
>  			    sprintf(volumename, "%s.backup", tentry.name);
> +#ifdef HAVE_REGEX_H
> +			    if (regexec(&re, volumename, 0, NULL, 0) == 0) {
> +				thismatch = VLSF_BACKVOL;
> +			    }
> +#else
>  			    if (re_exec(volumename)) {
>  				thismatch = VLSF_BACKVOL;
>  			    }
> +#endif
>  			} else {
>  			    thismatch = VLSF_BACKVOL;
>  			}
> @@ -1504,8 +1534,14 @@
>  			    } else {
>  				sprintf(volumename, "%s.readonly",
>  					tentry.name);
> +#ifdef HAVE_REGEX_H
> +			    if (regexec(&re, volumename, 0, NULL, 0) == 0) {
> +				thismatch = VLSF_ROVOL;
> +			    }
> +#else
>  				if (re_exec(volumename))
>  				    thismatch = VLSF_ROVOL;
> +#endif
>  			    }
>  			} else {
>  			    thismatch = VLSF_ROVOL;
> @@ -1566,6 +1602,9 @@
>      }
>
>    done:
> +    if (need_regfree)
> +	regfree(&re);
> +
>      if (errorcode) {
>  	COUNT_ABO;
>  	ubik_AbortTrans(trans);
> Index: src/volser/vos.c
> ===================================================================
> RCS file: /cvs/openafs/src/volser/vos.c,v
> retrieving revision 1.28
> diff -u -r1.28 vos.c
> --- src/volser/vos.c	15 Sep 2003 21:39:10 -0000	1.28
> +++ src/volser/vos.c	8 Oct 2003 05:10:05 -0000
> @@ -62,6 +62,13 @@
>  #endif
>  #include "volser_prototypes.h"
>
> +#ifdef AFS_FBSD_ENV
> +#define HAVE_REGEX_H
> +#endif
> +#ifdef HAVE_REGEX_H
> +#include <regex.h>
> +#endif
> +
>  struct tqElem {
>      afs_int32 volid;
>      struct tqElem *next;
> @@ -3928,6 +3935,20 @@
>      if (seenprefix) {
>  	for (ti = as->parms[0].items; ti; ti = ti->next) {
>  	    if (strncmp(ti->data, "^", 1) == 0) {
> +#ifdef HAVE_REGEX_H
> +		regex_t re;
> +		char errbuf[256];
> +
> +		code = regcomp(&re, ti->data, REG_BASIC | REG_NOSUB);
> +		if (code != 0) {
> +		    regerror(code, &re, errbuf, sizeof errbuf);
> +		    fprintf(STDERR,
> +			    "Unrecognizable -prefix regular expression: '%s': %s\n",
> +			    ti->data, errbuf);
> +		    exit(1);
> +		}
> +		regfree(&re);
> +#else
>  		ccode = (char *)re_comp(ti->data);
>  		if (ccode) {
>  		    fprintf(STDERR,
> @@ -3935,12 +3956,27 @@
>  			    ti->data, ccode);
>  		    exit(1);
>  		}
> +#endif
>  	    }
>  	}
>      }
>      if (seenxprefix) {
>  	for (ti = as->parms[4].items; ti; ti = ti->next) {
>  	    if (strncmp(ti->data, "^", 1) == 0) {
> +#ifdef HAVE_REGEX_H
> +		regex_t re;
> +		char errbuf[256];
> +
> +		code = regcomp(&re, ti->data, REG_BASIC | REG_NOSUB);
> +		if (code != 0) {
> +		    regerror(code, &re, errbuf, sizeof errbuf);
> +		    fprintf(STDERR,
> +			    "Unrecognizable -xprefix regular expression: '%s': %s\n",
> +			    ti->data, errbuf);
> +		    exit(1);
> +		}
> +		regfree(&re);
> +#else
>  		ccode = (char *)re_comp(ti->data);
>  		if (ccode) {
>  		    fprintf(STDERR,
> @@ -3948,6 +3984,7 @@
>  			    ti->data, ccode);
>  		    exit(1);
>  		}
> +#endif
>  	    }
>  	}
>      }
> @@ -4012,6 +4049,22 @@
>  	if (seenprefix) {
>  	    for (ti = as->parms[0].items; ti; ti = ti->next) {
>  		if (strncmp(ti->data, "^", 1) == 0) {
> +#ifdef HAVE_REGEX_H
> +		    regex_t re;
> +		    char errbuf[256];
> +
> +		    /* XXX -- should just do the compile once! */
> +		    code = regcomp(&re, ti->data, REG_BASIC | REG_NOSUB);
> +		    if (code != 0) {
> +			regerror(code, &re, errbuf, sizeof errbuf);
> +			fprintf(STDERR,
> +				"Error in -prefix regular expression: '%s': %s\n",
> +				ti->data, errbuf);
> +			exit(1);
> +		    }
> +		    match = (regexec(&re, vllist->name, 0, NULL, 0) == 0);
> +		    regfree(&re);
> +#else
>  		    ccode = (char *)re_comp(ti->data);
>  		    if (ccode) {
>  			fprintf(STDERR,
> @@ -4020,6 +4073,7 @@
>  			exit(1);
>  		    }
>  		    match = (re_exec(vllist->name) == 1);
> +#endif
>  		} else {
>  		    match =
>  			(strncmp(vllist->name, ti->data, strlen(ti->data)) ==
> @@ -4040,6 +4094,23 @@
>  	if (match && seenxprefix) {
>  	    for (ti = as->parms[4].items; ti; ti = ti->next) {
>  		if (strncmp(ti->data, "^", 1) == 0) {
> +#ifdef HAVE_REGEX_H
> +		    regex_t re;
> +		    char errbuf[256];
> +
> +		    /* XXX -- should just do the compile once! */
> +		    code = regcomp(&re, ti->data, REG_BASIC | REG_NOSUB);
> +		    if (code != 0) {
> +			regerror(code, &re, errbuf, sizeof errbuf);
> +			fprintf(STDERR,
> +				"Error in -xprefix regular expression: '%s': %s\n",
> +				ti->data, errbuf);
> +			exit(1);
> +		    }
> +		    if (regexec(&re, vllist->name, 0, NULL, 0) == 0)
> +			    match = 0;
> +		    regfree(&re);
> +#else
>  		    ccode = (char *)re_comp(ti->data);
>  		    if (ccode) {
>  			fprintf(STDERR,
> @@ -4051,6 +4122,7 @@
>  			match = 0;
>  			break;
>  		    }
> +#endif
>  		} else {
>  		    if (strncmp(vllist->name, ti->data, strlen(ti->data)) ==
>  			0) {
> _______________________________________________
> port-freebsd mailing list
> [email protected]
> https://lists.openafs.org/mailman/listinfo/port-freebsd
signature.asc (application/pgp-signature, 187 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (FreeBSD)

iD8DBQA/hevTpkWIXJRvi30RAnPPAJ9vfkQDrsULZGTk1wJlwjUTjrnLdACdHBmS
7rY/NKjE9+G1cC8yQKawNEE=
=qDCZ
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.