From: Matt Benjamin Date: Tue, 5 Jan 2010 02:31:27 +0000 (-0500) Subject: freebsd: CM changes targeting RELENG_8 X-Git-Tag: openafs-devel-1_5_69~36 X-Git-Url: http://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=90f91f4464f5785290040436b2d8cbe4b8ed5810 freebsd: CM changes targeting RELENG_8 Force all vnodes onto the fs mount queue when allocated. This fixes a long-standing vnode recycling problem. Don't call vgone() on a vnode whose refcount is 0. Always destroy vnodes in VOP_RECLAIM. This is work in progress towards fixing old reclaim bug mentioned in Rees comment. Hold vnode returned from gop_lookupname_user in afs_pioctl_syscall, to avoid it going inactive before we're finished. Also unlock it if necessary. Don't use custom vop_lock impl when AFS_FBSD80_ENV. Remove duplicate conditional code in vnode pretty-print (old cruft). Also don't format fid members as hex. Revert vn_lock exclusve in osi_VM_StoreAllSegments (fixes deadlock introduced by me in a 2009 changeset). Remove unused variables in osi_VM_StoreAllSegments. Change-Id: I9fd146d6f405382a20a75523ec2b75c62ac6d17a Reviewed-on: http://gerrit.openafs.org/1068 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- diff --git a/src/afs/FBSD/osi_vm.c b/src/afs/FBSD/osi_vm.c index 804b473..6a2f136 100644 --- a/src/afs/FBSD/osi_vm.c +++ b/src/afs/FBSD/osi_vm.c @@ -85,7 +85,9 @@ * therefore obsolescent. * * OSF/1 Locking: VN_LOCK has been called. - * XXX - should FreeBSD have done this, too? Certainly looks like it. + * We do not lock the vnode here, but instead require that it be exclusive + * locked by code calling osi_VM_StoreAllSegments directly, or scheduling it + * from the bqueue - Matt * Maybe better to just call vnode_pager_setsize()? */ int @@ -159,13 +161,7 @@ osi_VM_StoreAllSegments(struct vcache *avc) */ do { anyio = 0; -#ifdef AFS_FBSD80_ENV - lock_vnode(vp); -#endif if (VOP_GETVOBJECT(vp, &obj) == 0 && (obj->flags & OBJ_MIGHTBEDIRTY)) { -#ifdef AFS_FBSD80_ENV - unlock_vnode(vp); -#endif #ifdef AFS_FBSD50_ENV if (!vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread)) { #else @@ -180,10 +176,6 @@ osi_VM_StoreAllSegments(struct vcache *avc) vput(vp); } } -#ifdef AFS_FBSD80_ENV - else - unlock_vnode(vp); -#endif } while (anyio && (--tries > 0)); AFS_GLOCK(); ObtainWriteLock(&avc->lock, 94); @@ -202,8 +194,7 @@ void osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync) { struct vnode *vp; - struct vm_object *obj; - int anyio, tries, code; + int tries, code; SPLVAR; @@ -211,7 +202,7 @@ osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, int sync) if (vp->v_iflag & VI_DOOMED) { USERPRI; - return 0; + return; } if (vp->v_bufobj.bo_object != NULL) { diff --git a/src/afs/FBSD/osi_vnodeops.c b/src/afs/FBSD/osi_vnodeops.c index 442215c..4842e96 100644 --- a/src/afs/FBSD/osi_vnodeops.c +++ b/src/afs/FBSD/osi_vnodeops.c @@ -93,7 +93,7 @@ static vop_setattr_t afs_vop_setattr; static vop_strategy_t afs_vop_strategy; static vop_symlink_t afs_vop_symlink; static vop_write_t afs_vop_write; -#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD90_ENV) +#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD80_ENV) static vop_lock1_t afs_vop_lock; static vop_unlock_t afs_vop_unlock; static vop_islocked_t afs_vop_islocked; @@ -134,7 +134,7 @@ struct vop_vector afs_vnodeops = { .vop_strategy = afs_vop_strategy, .vop_symlink = afs_vop_symlink, .vop_write = afs_vop_write, -#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD90_ENV) +#if defined(AFS_FBSD70_ENV) && !defined(AFS_FBSD80_ENV) .vop_lock1 = afs_vop_lock, .vop_unlock = afs_vop_unlock, .vop_islocked = afs_vop_islocked, @@ -1516,15 +1516,11 @@ afs_vop_reclaim(struct vop_reclaim_args *ap) */ if (code) printf("afs_vop_reclaim: afs_FlushVCache failed code %d\n", code); -#ifdef AFS_FBSD60_ENV - else { - vnode_destroy_vobject(vp); -#ifndef AFS_FBSD70_ENV - vfs_hash_remove(vp); -#endif - vp->v_data = 0; - } -#endif + + /* basically, it must not fail */ + vnode_destroy_vobject(vp); + vp->v_data = 0; + return 0; } @@ -1578,17 +1574,10 @@ afs_vop_print(ap) register struct vcache *vc = VTOAFS(ap->a_vp); int s = vc->f.states; -#ifdef AFS_FBSD50_ENV - printf("tag %s, fid: %d.%x.%x.%x, opens %d, writers %d", vp->v_tag, + printf("tag %s, fid: %d.%d.%d.%d, opens %d, writers %d", vp->v_tag, (int)vc->f.fid.Cell, (u_int) vc->f.fid.Fid.Volume, (u_int) vc->f.fid.Fid.Vnode, (u_int) vc->f.fid.Fid.Unique, vc->opens, vc->execsOrWriters); -#else - printf("tag %d, fid: %ld.%x.%x.%x, opens %d, writers %d", vp->v_tag, - vc->f.fid.Cell, (u_int) vc->f.fid.Fid.Volume, - (u_int) vc->f.fid.Fid.Vnode, (u_int) vc->f.fid.Fid.Unique, vc->opens, - vc->execsOrWriters); -#endif printf("\n states%s%s%s%s%s", (s & CStatd) ? " statd" : "", (s & CRO) ? " readonly" : "", (s & CDirty) ? " dirty" : "", (s & CMAPPED) ? " mapped" : "", diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index ebfc6ac..42aa960 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -836,6 +836,9 @@ afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow) vp = (struct vnode *)dp->d_inode; #else code = gop_lookupname_user(path, AFS_UIOUSER, follow, &vp); +#if defined(AFS_FBSD80_ENV) /* XXX check on 7x */ + VN_HOLD(vp); +#endif /* AFS_FBSD80_ENV */ #endif /* AFS_LINUX22_ENV */ #endif /* AFS_AIX41_ENV */ AFS_GLOCK(); @@ -933,6 +936,10 @@ afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow) #ifdef AFS_LINUX22_ENV dput(dp); #else +#if defined(AFS_FBSD80_ENV) + if (VOP_ISLOCKED(vp)) + VOP_UNLOCK(vp, 0); +#endif /* AFS_FBSD80_ENV */ AFS_RELE(vp); /* put vnode back */ #endif } diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 3c5b3ed..3eed998 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -742,9 +742,9 @@ afs_AllocVCache(void) /* none free, making one is better than a panic */ afs_stats_cmperf.vcacheXAllocs++; /* count in case we have a leak */ tvc = (struct vcache *)afs_osi_Alloc(sizeof(struct vcache)); -#if defined(AFS_DARWIN_ENV) && !defined(UKERNEL) +#if (defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)) && !defined(UKERNEL) tvc->v = NULL; /* important to clean this, or use memset 0 */ -#endif +#endif /* DARWIN || XBSD && !UKERNEL */ #ifdef KERNEL_HAVE_PIN pin((char *)tvc, sizeof(struct vcache)); /* XXX */ #endif @@ -889,7 +889,19 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) * XXX assume FreeBSD is the same for now. */ AFS_GUNLOCK(); +#if defined(AFS_FBSD80_ENV) + /* vgone() is correct, but v_usecount is assumed not + * to be 0, and I suspect that currently our usage ensures that + * in fact it will */ + if (vrefcnt(AFSTOV(tvc)) < 1) { + vref(AFSTOV(tvc)); + } + vn_lock(AFSTOV(tvc), LK_EXCLUSIVE | LK_RETRY); /* !glocked */ +#endif vgone(AFSTOV(tvc)); +#if defined(AFS_FBSD80_ENV) + VOP_UNLOCK(AFSTOV(tvc), 0); +#endif fv_slept = 0; code = 0; AFS_GLOCK(); @@ -1036,6 +1048,14 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) if (getnewvnode(VT_AFS, afs_globalVFS, afs_vnodeop_p, &vp)) #endif panic("afs getnewvnode"); /* can't happen */ +#ifdef AFS_FBSD70_ENV + /* XXX verified on 80--TODO check on 7x */ + if (!vp->v_mount) { + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); /* !glocked */ + insmntque(vp, afs_globalVFS); + VOP_UNLOCK(vp, 0); + } +#endif AFS_GLOCK(); ObtainWriteLock(&afs_xvcache,339); if (tvc->v != NULL) { @@ -1156,11 +1176,6 @@ afs_NewVCache(struct VenusFid *afid, struct server *serverp) tvc->v.v_next = gnodepnt->gn_vnode; /*Single vnode per gnode for us! */ gnodepnt->gn_vnode = &tvc->v; #endif -#ifdef AFS_FBSD70_ENV -#ifndef AFS_FBSD80_ENV /* yup. they put it back. */ - insmntque(AFSTOV(tvc), afs_globalVFS); -#endif -#endif #if defined(AFS_SGI_ENV) VN_SET_DPAGES(&(tvc->v), (struct pfdat *)NULL); osi_Assert((tvc->v.v_flag & VINACT) == 0);