From d871033be74049e92d0034505d52ab0b4ee99a84 Mon Sep 17 00:00:00 2001 From: Jim Rees Date: Wed, 20 Nov 2002 23:00:33 +0000 Subject: [PATCH] openbsd-20021120 OpenBSD: Hold volume info file vnode until shutdown Pass proc struct * to HandleFlock Get va_atime.tv_nsec right in getattr --- src/afs/OBSD/osi_vnodeops.c | 2 +- src/afs/VNOPS/afs_vnop_attrs.c | 46 +++++++++--------------- src/afs/VNOPS/afs_vnop_flock.c | 70 ++++++++++++++++++------------------ src/afs/VNOPS/afs_vnop_write.c | 8 ++++- src/afs/afs_daemons.c | 3 ++ src/afs/afs_init.c | 81 +++++++++++++++++++++++++++++++----------- src/afs/afs_vcache.c | 5 +++ 7 files changed, 127 insertions(+), 88 deletions(-) diff --git a/src/afs/OBSD/osi_vnodeops.c b/src/afs/OBSD/osi_vnodeops.c index 7a78fe8..436ef9f 100644 --- a/src/afs/OBSD/osi_vnodeops.c +++ b/src/afs/OBSD/osi_vnodeops.c @@ -392,7 +392,7 @@ afs_nbsd_close(ap) int code; AFS_GLOCK(); - code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred); + code = afs_close(VTOAFS(ap->a_vp), ap->a_fflag, ap->a_cred, ap->a_p); AFS_GUNLOCK(); return code; } diff --git a/src/afs/VNOPS/afs_vnop_attrs.c b/src/afs/VNOPS/afs_vnop_attrs.c index de017db..00974cf 100644 --- a/src/afs/VNOPS/afs_vnop_attrs.c +++ b/src/afs/VNOPS/afs_vnop_attrs.c @@ -102,32 +102,28 @@ int afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs) * anyway, so the difference between 512K and 1000000 shouldn't matter * much, and "&" is a lot faster than "%". */ -#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_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_ctime.tv_nsec = 0; 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) +#elif defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_AIX41_ENV) || defined(AFS_OBSD_ENV) attrs->va_atime.tv_nsec = attrs->va_mtime.tv_nsec = - attrs->va_ctime.tv_nsec = - (hgetlo(avc->m.DataVersion) & 0x7ffff) * 1000; -#if defined(AFS_AIX41_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) - attrs->va_blocksize = PAGESIZE; /* XXX Was 8192 XXX */ + attrs->va_ctime.tv_nsec = (hgetlo(avc->m.DataVersion) & 0x7ffff) * 1000; #else - attrs->va_blksize = PAGESIZE; /* XXX Was 8192 XXX */ + attrs->va_atime.tv_usec = attrs->va_mtime.tv_usec = + attrs->va_ctime.tv_usec = (hgetlo(avc->m.DataVersion) & 0x7ffff); +#endif +#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV) || defined(AFS_OSF_ENV) + attrs->va_flags = 0; #endif +#if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) + attrs->va_blksize = PAGESIZE; /* XXX Was 8192 XXX */ #else - attrs->va_atime.tv_usec = attrs->va_mtime.tv_usec = - attrs->va_ctime.tv_usec = - (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 @@ -140,42 +136,32 @@ int afs_CopyOutAttrs(register struct vcache *avc, register struct vattr *attrs) #else attrs->va_rdev = 1; #endif + /* * 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) -#ifdef va_size_rsv - attrs->va_size_rsv = 0; -#endif -/* XXX do this */ -/* attrs->va_gen = avc->m.DataVersion;*/ - attrs->va_flags = 0; -#endif /* AFS_OSF_ENV || AFS_DARWIN_ENV */ - #if !defined(AFS_OSF_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV) #if !defined(AFS_HPUX_ENV) #ifdef AFS_SUN5_ENV attrs->va_nblocks = (attrs->va_size? ((attrs->va_size + 1023)>>10) << 1 : 0); -#else -#if defined(AFS_SGI_ENV) +#elif defined(AFS_SGI_ENV) attrs->va_blocks = BTOBB(attrs->va_size); #else attrs->va_blocks = (attrs->va_size? ((attrs->va_size + 1023)>>10) << 1 : 0); #endif -#endif #else /* !defined(AFS_HPUX_ENV) */ attrs->va_blocks = (attrs->va_size? ((attrs->va_size + 1023)>>10) : 0); #endif /* !defined(AFS_HPUX_ENV) */ -#else /* ! AFS_OSF_ENV && !AFS_XBSD_ENV */ +#else /* ! AFS_OSF_ENV && !AFS_DARWIN_ENV && !AFS_XBSD_ENV */ attrs->va_bytes = (attrs->va_size? (attrs->va_size + 1023) : 1024); #ifdef va_bytes_rsv attrs->va_bytes_rsv = -1; #endif -#endif /* ! AFS_OSF_ENV */ +#endif /* ! AFS_OSF_ENV && !AFS_DARWIN_ENV && !AFS_XBSD_ENV */ #ifdef AFS_LINUX22_ENV - /* And linux has it's own stash as well. */ + /* And linux has its own stash as well. */ vattr2inode(AFSTOV(avc), attrs); #endif #ifdef notdef diff --git a/src/afs/VNOPS/afs_vnop_flock.c b/src/afs/VNOPS/afs_vnop_flock.c index 2d84703..b586a91 100644 --- a/src/afs/VNOPS/afs_vnop_flock.c +++ b/src/afs/VNOPS/afs_vnop_flock.c @@ -242,65 +242,65 @@ int HandleFlock(register struct vcache *avc, int acom, */ if ((avc->flockCount < 0) && (getpid() != avc->ownslock)) { #ifdef AFS_AIX41_ENV - if (onlymine || (getppid() != avc->ownslock)) { + if (onlymine || (getppid() != avc->ownslock)) { #else - if (onlymine || (u.u_procp->p_ppid != avc->ownslock)) { + if (onlymine || (u.u_procp->p_ppid != avc->ownslock)) { #endif - ReleaseWriteLock(&avc->lock); - return 0; - } + ReleaseWriteLock(&avc->lock); + return 0; + } } #endif if (lockIdcmp2(&flock, avc, NULL, onlymine, clid)) { - ReleaseWriteLock(&avc->lock); - return 0; + ReleaseWriteLock(&avc->lock); + return 0; } #ifdef AFS_AIX_ENV avc->ownslock = 0; #endif if (avc->flockCount == 0) { - ReleaseWriteLock(&avc->lock); - return 0 /*ENOTTY*/; - /* no lock held */ + ReleaseWriteLock(&avc->lock); + return 0 /*ENOTTY*/; + /* no lock held */ } /* unlock the lock */ if (avc->flockCount > 0) { - slpp = &avc->slocks; - for (slp = *slpp; slp;) { - if (!lockIdcmp2(&flock, avc, slp, onlymine, clid)) { - avc->flockCount--; - tlp = *slpp = slp->next; - osi_FreeSmallSpace(slp); - slp = tlp; - } else { - slpp = &slp->next; - slp = *slpp; + slpp = &avc->slocks; + for (slp = *slpp; slp;) { + if (!lockIdcmp2(&flock, avc, slp, onlymine, clid)) { + avc->flockCount--; + tlp = *slpp = slp->next; + osi_FreeSmallSpace(slp); + slp = tlp; + } else { + slpp = &slp->next; + slp = *slpp; + } } - } } else if (avc->flockCount == -1) { - afs_StoreAllSegments(avc, areq, AFS_ASYNC); /* fsync file early */ - avc->flockCount = 0; - /* And remove the (only) exclusive lock entry from the list... */ - osi_FreeSmallSpace(avc->slocks); - avc->slocks = 0; + afs_StoreAllSegments(avc, areq, AFS_ASYNC); /* fsync file early */ + avc->flockCount = 0; + /* And remove the (only) exclusive lock entry from the list... */ + osi_FreeSmallSpace(avc->slocks); + avc->slocks = 0; } if (avc->flockCount == 0) { do { tc = afs_Conn(&avc->fid, areq, SHARED_LOCK); if (tc) { - XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK); - RX_AFS_GUNLOCK(); - code = RXAFS_ReleaseLock(tc->id, (struct AFSFid *) - &avc->fid.Fid, &tsync); - RX_AFS_GLOCK(); - XSTATS_END_TIME; + XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_RELEASELOCK); + RX_AFS_GUNLOCK(); + code = RXAFS_ReleaseLock(tc->id, (struct AFSFid *) + &avc->fid.Fid, &tsync); + RX_AFS_GLOCK(); + XSTATS_END_TIME; } else code = -1; } while - (afs_Analyze(tc, code, &avc->fid, areq, - AFS_STATS_FS_RPCIDX_RELEASELOCK, - SHARED_LOCK, NULL)); + (afs_Analyze(tc, code, &avc->fid, areq, + AFS_STATS_FS_RPCIDX_RELEASELOCK, + SHARED_LOCK, NULL)); } } else { diff --git a/src/afs/VNOPS/afs_vnop_write.c b/src/afs/VNOPS/afs_vnop_write.c index 8e014b0..9ce7319 100644 --- a/src/afs/VNOPS/afs_vnop_write.c +++ b/src/afs/VNOPS/afs_vnop_write.c @@ -766,6 +766,7 @@ int afs_closex(register struct file *afd) /* handle any closing cleanup stuff */ +int #ifdef AFS_SGI_ENV afs_close(OSI_VC_ARG(avc), aflags, lastclose, #if !defined(AFS_SGI65_ENV) @@ -792,6 +793,9 @@ afs_close(OSI_VC_ARG(avc), aflags, count, offset, acred) afs_close(OSI_VC_ARG(avc), aflags, count, acred) #endif int count; +#elif defined(AFS_OBSD_ENV) +afs_close(OSI_VC_ARG(avc), aflags, acred, aproc) + struct proc *aproc; #else afs_close(OSI_VC_ARG(avc), aflags, acred) #endif @@ -861,6 +865,8 @@ afs_close(OSI_VC_ARG(avc), aflags, acred) if (avc->flockCount) { /* Release Lock */ #if defined(AFS_OSF_ENV) || defined(AFS_SUN_ENV) HandleFlock(avc, LOCK_UN, &treq, u.u_procp->p_pid, 1/*onlymine*/); +#elif defined(AFS_OBSD_ENV) + HandleFlock(avc, LOCK_UN, &treq, aproc->p_pid, 1/*onlymine*/); #else HandleFlock(avc, LOCK_UN, &treq, 0, 1/*onlymine*/); #endif @@ -966,7 +972,7 @@ afs_close(OSI_VC_ARG(avc), aflags, acred) } - +int #ifdef AFS_OSF_ENV afs_fsync(avc, fflags, acred, waitfor) int fflags; diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c index e93ba66..afa8e47 100644 --- a/src/afs/afs_daemons.c +++ b/src/afs/afs_daemons.c @@ -162,6 +162,9 @@ void afs_Daemon(void) DFlush(); /* write out dir buffers */ afs_WriteThroughDSlots(); /* write through cacheinfo entries */ afs_FlushActiveVcaches(1);/* keep flocks held & flush nfs writes */ +#ifdef AFS_DISCON_ENV + afs_StoreDirtyVcaches(); +#endif afs_CheckRXEpoch(); last1MinCheck = now; } diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c index 8b35c52..3162537 100644 --- a/src/afs/afs_init.c +++ b/src/afs/afs_init.c @@ -40,6 +40,9 @@ char *afs_sysnamelist[MAXNUMSYSNAMES]; /* For support of a list of sysname */ int afs_sysnamecount = 0; struct volume *Initialafs_freeVolList; int afs_memvolumes = 0; +#ifdef AFS_OBSD_ENV +static struct vnode *volumeVnode; +#endif /* * Initialization order is important. Must first call afs_CacheInit, @@ -216,22 +219,13 @@ void afs_ComputeCacheParms(void) /* - * afs_InitVolumeInfo - * - * Description: - * Set up the volume info storage file. - * - * Parameters: - * afile : the file to be declared to be the volume info storage - * file for AFS. It must be already truncated to 0 length. - * - * Environment: - * This function is called only during initialization. + * LookupInodeByPath * - * WARNING: Data will be written to this file over time by AFS. + * Look up inode given a file name. + * Optionally return the vnode too. + * If the vnode is not returned, we rele it. */ - -static int LookupInodeByPath(char *filename, ino_t *inode) +static int LookupInodeByPath(char *filename, ino_t *inode, struct vnode **fvpp) { afs_int32 code; @@ -246,11 +240,15 @@ static int LookupInodeByPath(char *filename, ino_t *inode) code = gop_lookupname(filename, AFS_UIOSYS, 0, NULL, &filevp); if (code) return code; *inode = afs_vnodeToInumber(filevp); -#ifdef AFS_DEC_ENV - grele(filevp); + if (fvpp) + *fvpp = filevp; + else { +#if defined(AFS_DEC_ENV) + grele(filevp); #else - AFS_RELE((struct vnode *)filevp); + AFS_RELE(filevp); #endif + } #endif /* AFS_LINUX22_ENV */ return 0; @@ -261,18 +259,52 @@ int afs_InitCellInfo(char *afile) ino_t inode; int code; - code = LookupInodeByPath(afile, &inode); + code = LookupInodeByPath(afile, &inode, NULL); return afs_cellname_init(inode, code); } +/* + * afs_InitVolumeInfo + * + * Description: + * Set up the volume info storage file. + * + * Parameters: + * afile : the file to be declared to be the volume info storage + * file for AFS. It must be already truncated to 0 length. + * + * Environment: + * This function is called only during initialization. + * + * WARNING: Data will be written to this file over time by AFS. + */ + int afs_InitVolumeInfo(char *afile) { int code; struct osi_file *tfile; AFS_STATCNT(afs_InitVolumeInfo); - code = LookupInodeByPath(afile, &volumeInode); - if (code) return code; +#if defined(AFS_OBSD_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. + * SetupVolume->GetVolSlot->UFSGetVolSlot->{GetVolCache or WriteVolCache} + * ->osi_UFSOpen->VFS_VGET()->ffs_vget->getnewvnode->vgone on some vnode. + * If it's AFS, then ->vclean->afs_nbsd_reclaim->FlushVCache->QueueVCB-> + * GetVolume->FindVolume-> waits on afs_xvolume lock ! + * + * In general, anything that's called with afs_xvolume locked must not + * end up calling getnewvnode(). The only cases I've found so far + * are things which try to get the volumeInode, and since we keep + * it in the cache... + */ + code = LookupInodeByPath(afile, &volumeInode, &volumeVnode); +#else + code = LookupInodeByPath(afile, &volumeInode, NULL); +#endif + if (code) + return code; tfile = afs_CFileOpen(volumeInode); afs_CFileTruncate(tfile, 0); afs_CFileClose(tfile); @@ -633,9 +665,16 @@ void shutdown_cache(void) afs_cacheFiles = afs_cacheBlocks = 0; pag_epoch = maxIHint = nihints = usedihint = 0; pagCounter = 0; +#ifdef AFS_OBSD_ENV + AFS_RELE(volumeVnode); /* let it go, finally. */ + volumeVnode = NULL; + if (cacheDev.held_vnode) { + AFS_RELE(cacheDev.held_vnode); + cacheDev.held_vnode = NULL; + } +#endif cacheInode = volumeInode = (ino_t)0; - cacheInfoModTime = 0; afs_fsfragsize = 1023; diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index efb311c..d26dd5a 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -1737,6 +1737,11 @@ loop: return tvc; } #endif /* AFS_OSF_ENV */ +#ifdef AFS_OBSD_ENV + VOP_LOCK(AFSTOV(tvc), LK_EXCLUSIVE | LK_RETRY, curproc); + uvm_vnp_uncache(AFSTOV(tvc)); + VOP_UNLOCK(AFSTOV(tvc), 0, curproc); +#endif ObtainWriteLock(&afs_xcbhash, 464); tvc->states &= ~CUnique; -- 1.9.4