From: Andrew Deason Date: Thu, 17 Jan 2019 21:45:36 +0000 (-0600) Subject: afs: Introduce afs_IsDCacheFresh X-Git-Tag: openafs-devel-1_9_0~280 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=0d8ce846ab2e6c45166a61f04eb3af271cbd27db afs: Introduce afs_IsDCacheFresh Numerous places in libafs check the DV of a dcache against the DV of the vcache for the same file, in order to check if the dcache is up to date and can be used. Consolidate all of these checks into a new function, afs_IsDCacheFresh, to make it easier for future commits to alter this logic. This commit should have no visible impact; it is just code reorganization. Change-Id: Iedc02b0f5d7d0542ab00ff1effdde03c2a851df4 Reviewed-on: https://gerrit.openafs.org/13435 Reviewed-by: Benjamin Kaduk Tested-by: Andrew Deason --- diff --git a/src/afs/LINUX/osi_export.c b/src/afs/LINUX/osi_export.c index a3175b5..926bd0d 100644 --- a/src/afs/LINUX/osi_export.c +++ b/src/afs/LINUX/osi_export.c @@ -349,7 +349,7 @@ redo: */ while ((adp->f.states & CStatd) && (tdc->dflags & DFFetching) - && hsame(adp->f.m.DataVersion, tdc->f.versionNo)) { + && afs_IsDCacheFresh(tdc, adp)) { ReleaseReadLock(&tdc->lock); ReleaseSharedLock(&adp->lock); afs_osi_Sleep(&tdc->validPos); @@ -357,7 +357,7 @@ redo: ObtainReadLock(&tdc->lock); } if (!(adp->f.states & CStatd) - || !hsame(adp->f.m.DataVersion, tdc->f.versionNo)) { + || !afs_IsDCacheFresh(tdc, adp)) { ReleaseReadLock(&tdc->lock); ReleaseSharedLock(&adp->lock); afs_PutDCache(tdc); @@ -770,7 +770,7 @@ redo: */ while ((vcp->f.states & CStatd) && (tdc->dflags & DFFetching) - && hsame(vcp->f.m.DataVersion, tdc->f.versionNo)) { + && afs_IsDCacheFresh(tdc, vcp)) { ReleaseReadLock(&tdc->lock); ReleaseReadLock(&vcp->lock); afs_osi_Sleep(&tdc->validPos); @@ -778,7 +778,7 @@ redo: ObtainReadLock(&tdc->lock); } if (!(vcp->f.states & CStatd) - || !hsame(vcp->f.m.DataVersion, tdc->f.versionNo)) { + || !afs_IsDCacheFresh(tdc, vcp)) { ReleaseReadLock(&tdc->lock); ReleaseReadLock(&vcp->lock); afs_PutDCache(tdc); diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index e3422ca..cfb8743 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -368,7 +368,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) */ while ((avc->f.states & CStatd) && (tdc->dflags & DFFetching) - && hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { + && afs_IsDCacheFresh(tdc, avc)) { ReleaseReadLock(&tdc->lock); ReleaseWriteLock(&avc->lock); afs_osi_Sleep(&tdc->validPos); @@ -376,7 +376,7 @@ afs_linux_readdir(struct file *fp, void *dirbuf, filldir_t filldir) ObtainReadLock(&tdc->lock); } if (!(avc->f.states & CStatd) - || !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { + || !afs_IsDCacheFresh(tdc, avc)) { ReleaseReadLock(&tdc->lock); ReleaseWriteLock(&avc->lock); afs_PutDCache(tdc); @@ -2256,7 +2256,7 @@ afs_linux_readpage_fastpath(struct file *fp, struct page *pp, int *codep) ObtainReadLock(&tdc->lock); /* Is the dcache we've been given currently up to date */ - if (!hsame(avc->f.m.DataVersion, tdc->f.versionNo) || + if (!afs_IsDCacheFresh(tdc, avc) || (tdc->dflags & DFFetching)) goto out; @@ -2687,7 +2687,7 @@ afs_linux_readpages(struct file *fp, struct address_space *mapping, AFS_GLOCK(); if ((tdc = afs_FindDCache(avc, offset))) { ObtainReadLock(&tdc->lock); - if (!hsame(avc->f.m.DataVersion, tdc->f.versionNo) || + if (!afs_IsDCacheFresh(tdc, avc) || (tdc->dflags & DFFetching)) { ReleaseReadLock(&tdc->lock); afs_PutDCache(tdc); diff --git a/src/afs/SOLARIS/osi_vnodeops.c b/src/afs/SOLARIS/osi_vnodeops.c index 361a0e5..e2cedf0 100644 --- a/src/afs/SOLARIS/osi_vnodeops.c +++ b/src/afs/SOLARIS/osi_vnodeops.c @@ -350,7 +350,7 @@ afs_GetOnePage(struct vnode *vp, u_offset_t off, u_int alen, u_int *protp, /* Check to see whether the cache entry is still valid */ if (!(avc->f.states & CStatd) - || !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { + || !afs_IsDCacheFresh(tdc, avc)) { ReleaseReadLock(&tdc->lock); ReleaseReadLock(&avc->lock); afs_PutDCache(tdc); @@ -886,12 +886,12 @@ afs_nfsrdwr(struct vcache *avc, struct uio *auio, enum uio_rw arw, AFS_GLOCK(); dcp_newpage = afs_FindDCache(avc, pageBase); if (dcp_newpage - && hsame(avc->f.m.DataVersion, dcp_newpage->f.versionNo)) { + && afs_IsDCacheFresh(dcp_newpage, avc)) { ObtainWriteLock(&avc->lock, 251); ObtainWriteLock(&avc->vlock, 576); ObtainReadLock(&dcp_newpage->lock); if ((avc->activeV == 0) - && hsame(avc->f.m.DataVersion, dcp_newpage->f.versionNo) + && afs_IsDCacheFresh(dcp_newpage, avc) && !(dcp_newpage->dflags & (DFFetching))) { AFS_GUNLOCK(); segmap_pagecreate(segkmap, raddr, rsize, 1); diff --git a/src/afs/VNOPS/afs_vnop_create.c b/src/afs/VNOPS/afs_vnop_create.c index c4d7c70..6d1df4f 100644 --- a/src/afs/VNOPS/afs_vnop_create.c +++ b/src/afs/VNOPS/afs_vnop_create.c @@ -149,7 +149,7 @@ afs_create(OSI_VC_DECL(adp), char *aname, struct vattr *attrs, * received a callback while we were waiting for the write lock. */ if (!(adp->f.states & CStatd) - || (tdc && !hsame(adp->f.m.DataVersion, tdc->f.versionNo))) { + || (tdc && !afs_IsDCacheFresh(tdc, adp))) { ReleaseWriteLock(&adp->lock); if (tdc) { ReleaseSharedLock(&tdc->lock); @@ -543,7 +543,7 @@ afs_LocalHero(struct vcache *avc, struct dcache *adc, if (adc) { /* does what's in the dcache *now* match what's in the vcache *now*, * and do we have a valid callback? if not, our local copy is not "ok" */ - ok = (hsame(avc->f.m.DataVersion, adc->f.versionNo) && avc->callback + ok = (afs_IsDCacheFresh(adc, avc) && avc->callback && (avc->f.states & CStatd) && avc->cbExpires >= osi_Time()); } else { ok = 0; diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 08ad2af..8146957 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -773,7 +773,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) */ while ((adp->f.states & CStatd) && (dcp->dflags & DFFetching) - && hsame(adp->f.m.DataVersion, dcp->f.versionNo)) { + && afs_IsDCacheFresh(dcp, adp)) { afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT, ICL_TYPE_STRING, __FILE__, ICL_TYPE_INT32, __LINE__, ICL_TYPE_POINTER, dcp, ICL_TYPE_INT32, dcp->dflags); @@ -784,7 +784,7 @@ afs_DoBulkStat(struct vcache *adp, long dirCookie, struct vrequest *areqp) ObtainReadLock(&dcp->lock); } if (!(adp->f.states & CStatd) - || !hsame(adp->f.m.DataVersion, dcp->f.versionNo)) { + || !afs_IsDCacheFresh(dcp, adp)) { ReleaseReadLock(&dcp->lock); ReleaseReadLock(&adp->lock); afs_PutDCache(dcp); @@ -1643,7 +1643,7 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, afs_ucred_t *acr if (!afs_InReadDir(adp)) { while ((adp->f.states & CStatd) && (tdc->dflags & DFFetching) - && hsame(adp->f.m.DataVersion, tdc->f.versionNo)) { + && afs_IsDCacheFresh(tdc, adp)) { ReleaseReadLock(&tdc->lock); ReleaseReadLock(&adp->lock); afs_osi_Sleep(&tdc->validPos); @@ -1651,7 +1651,7 @@ afs_lookup(OSI_VC_DECL(adp), char *aname, struct vcache **avcp, afs_ucred_t *acr ObtainReadLock(&tdc->lock); } if (!(adp->f.states & CStatd) - || !hsame(adp->f.m.DataVersion, tdc->f.versionNo)) { + || !afs_IsDCacheFresh(tdc, adp)) { ReleaseReadLock(&tdc->lock); ReleaseReadLock(&adp->lock); afs_PutDCache(tdc); diff --git a/src/afs/VNOPS/afs_vnop_read.c b/src/afs/VNOPS/afs_vnop_read.c index 1b1c682..369d60b 100644 --- a/src/afs/VNOPS/afs_vnop_read.c +++ b/src/afs/VNOPS/afs_vnop_read.c @@ -190,7 +190,7 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, * 2 requests never return a null dcache entry, btw. */ if (!(tdc->dflags & DFFetching) - && !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { + && !afs_IsDCacheFresh(tdc, avc)) { /* have cache entry, it is not coming in now, * and we'll need new data */ tagain: @@ -270,7 +270,7 @@ afs_read(struct vcache *avc, struct uio *auio, afs_ucred_t *acred, } else { /* no longer fetching, verify data version * (avoid new GetDCache call) */ - if (hsame(avc->f.m.DataVersion, tdc->f.versionNo) + if (afs_IsDCacheFresh(tdc, avc) && ((len = tdc->validPos - filePos) > 0)) { offset = filePos - AFS_CHUNKTOBASE(tdc->f.chunk); } else { diff --git a/src/afs/VNOPS/afs_vnop_readdir.c b/src/afs/VNOPS/afs_vnop_readdir.c index 9efe8eb..7bfc629 100644 --- a/src/afs/VNOPS/afs_vnop_readdir.c +++ b/src/afs/VNOPS/afs_vnop_readdir.c @@ -692,7 +692,7 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred) */ while ((avc->f.states & CStatd) && (tdc->dflags & DFFetching) - && hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { + && afs_IsDCacheFresh(tdc, avc)) { afs_Trace4(afs_iclSetp, CM_TRACE_DCACHEWAIT, ICL_TYPE_STRING, __FILE__, ICL_TYPE_INT32, __LINE__, ICL_TYPE_POINTER, tdc, ICL_TYPE_INT32, tdc->dflags); @@ -703,7 +703,7 @@ afs_readdir(OSI_VC_DECL(avc), struct uio *auio, afs_ucred_t *acred) ObtainReadLock(&tdc->lock); } if (!(avc->f.states & CStatd) - || !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { + || !afs_IsDCacheFresh(tdc, avc)) { ReleaseReadLock(&tdc->lock); ReleaseReadLock(&avc->lock); afs_PutDCache(tdc); diff --git a/src/afs/VNOPS/afs_vnop_remove.c b/src/afs/VNOPS/afs_vnop_remove.c index f1e1faf..a563652 100644 --- a/src/afs/VNOPS/afs_vnop_remove.c +++ b/src/afs/VNOPS/afs_vnop_remove.c @@ -235,7 +235,7 @@ afs_remove(OSI_VC_DECL(adp), char *aname, afs_ucred_t *acred) * received a callback while we were waiting for the write lock. */ if (!(adp->f.states & CStatd) - || (tdc && !hsame(adp->f.m.DataVersion, tdc->f.versionNo))) { + || (tdc && !afs_IsDCacheFresh(tdc, adp))) { ReleaseWriteLock(&adp->lock); if (tdc) { ReleaseSharedLock(&tdc->lock); diff --git a/src/afs/VNOPS/afs_vnop_rename.c b/src/afs/VNOPS/afs_vnop_rename.c index 2d4b9c1..fcf2bcb 100644 --- a/src/afs/VNOPS/afs_vnop_rename.c +++ b/src/afs/VNOPS/afs_vnop_rename.c @@ -135,7 +135,7 @@ afsrename(struct vcache *aodp, char *aname1, struct vcache *andp, */ if (tdc1) { if (!(aodp->f.states & CStatd) - || !hsame(aodp->f.m.DataVersion, tdc1->f.versionNo)) { + || !afs_IsDCacheFresh(tdc1, aodp)) { ReleaseWriteLock(&aodp->lock); if (!oneDir) { diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 15e63ff..c6a3bfb 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -1737,6 +1737,24 @@ afs_AllocDCache(struct dcache **adc, struct vcache *avc, afs_int32 chunk, return 0; } +/*! + * Check if a dcache is "fresh". That is, if the dcache's DV matches the DV of + * the vcache for that file. + * + * \param adc The dcache to check + * \param avc The vcache for adc + * + * \return 1 if the dcache does match avc's DV; 0 otherwise. + */ +int +afs_IsDCacheFresh(struct dcache *adc, struct vcache *avc) +{ + if (!hsame(adc->f.versionNo, avc->f.m.DataVersion)) { + return 0; + } + return 1; +} + /* * afs_GetDCache * @@ -1775,7 +1793,7 @@ void updateV2DC(int lockVc, struct vcache *v, struct dcache *d, int src) { if (!lockVc || 0 == NBObtainWriteLock(&v->lock, src)) { - if (hsame(v->f.m.DataVersion, d->f.versionNo) && v->callback) + if (afs_IsDCacheFresh(d, v) && v->callback) v->dchint = d; if (lockVc) ReleaseWriteLock(&v->lock); @@ -1885,7 +1903,7 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte, ReleaseReadLock(&afs_xdcache); shortcut = 1; - if (hsame(tdc->f.versionNo, avc->f.m.DataVersion) + if (afs_IsDCacheFresh(tdc, avc) && !(tdc->dflags & DFFetching)) { afs_stats_cmperf.dcacheHits++; @@ -2122,7 +2140,7 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte, if (AFS_CHUNKTOBASE(chunk) >= avc->f.m.Length && #endif #endif /* defined(AFS_AIX32_ENV) || defined(AFS_SGI_ENV) */ - !hsame(avc->f.m.DataVersion, tdc->f.versionNo)) + !afs_IsDCacheFresh(tdc, avc)) doReallyAdjustSize = 1; if (doReallyAdjustSize || overWriteWholeChunk) { @@ -2186,7 +2204,7 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte, * avc->lock(W) if !setLocks || slowPass * tdc->lock(S) */ - if (!hsame(avc->f.m.DataVersion, tdc->f.versionNo) && !overWriteWholeChunk) { + if (!afs_IsDCacheFresh(tdc, avc) && !overWriteWholeChunk) { /* * Version number mismatch. */ @@ -2256,7 +2274,7 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte, */ /* Watch for standard race condition around osi_FlushText */ - if (hsame(avc->f.m.DataVersion, tdc->f.versionNo)) { + if (afs_IsDCacheFresh(tdc, avc)) { updateV2DC(setLocks, avc, tdc, 569); /* set hint */ afs_stats_cmperf.dcacheHits++; ConvertWToSLock(&tdc->lock); @@ -3575,7 +3593,7 @@ afs_ObtainDCacheForWriting(struct vcache *avc, afs_size_t filePos, tdc = afs_FindDCache(avc, filePos); if (tdc) { ObtainWriteLock(&tdc->lock, 658); - if (!hsame(tdc->f.versionNo, avc->f.m.DataVersion) + if (!afs_IsDCacheFresh(tdc, avc) || (tdc->dflags & DFFetching)) { ReleaseWriteLock(&tdc->lock); afs_PutDCache(tdc); diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 615b0bf..d5ecb25 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -288,6 +288,7 @@ extern struct dcache *afs_ObtainDCacheForWriting(struct vcache *avc, int noLock); extern void afs_PopulateDCache(struct vcache *avc, afs_size_t apos, struct vrequest *areq); +extern int afs_IsDCacheFresh(struct dcache *adc, struct vcache *avc); /* afs_disconnected.c */