/* Try to invalidate pages, for "fs flush" or "fs flushv"; or * try to free pages, when deleting a file. * * Locking: the vcache entry's lock is held. It may be dropped and * re-obtained. */ void osi_VM_TryToSmush(struct vcache *avc, struct AFS_UCRED *acred, int sync) { struct vnode *vp = AFSTOV(avc); /* Flush the delayed write blocks associated with this vnode * from the buffer cache */ if ((vp->v_flag & VTEXT) == 0) { mpurge(vp); } /* Mark the cached blocks on the free list as invalid; it invalidates blocks * associated with vp which are on the freelist. */ binvalfree(vp); mpurge(vp); }
void osi_FlushText_really(struct vcache *vp) { afs_hyper_t fdv; /* version before which we'll flush */ AFS_STATCNT(osi_FlushText); /* see if we've already flushed this data version */ if (hcmp(vp->f.m.DataVersion, vp->flushDV) <= 0) return; ObtainWriteLock(&afs_ftf, 317); hset(fdv, vp->f.m.DataVersion); /* why this disgusting code below? * xuntext, called by xrele, doesn't notice when it is called * with a freed text object. Sun continually calls xrele or xuntext * without any locking, as long as VTEXT is set on the * corresponding vnode. * But, if the text object is locked when you check the VTEXT * flag, several processes can wait in xuntext, waiting for the * text lock; when the second one finally enters xuntext's * critical region, the text object is already free, but the check * was already done by xuntext's caller. * Even worse, it turns out that xalloc locks the text object * before reading or stating a file via the vnode layer. Thus, we * could end up in getdcache, being asked to bring in a new * version of a file, but the corresponding text object could be * locked. We can't flush the text object without causing * deadlock, so now we just don't try to lock the text object * unless it is guaranteed to work. And we try to flush the text * when we need to a bit more often at the vnode layer. Sun * really blew the vm-cache flushing interface. */ #if defined (AFS_HPUX_ENV) if (vp->v.v_flag & VTEXT) { xrele(vp); if (vp->v.v_flag & VTEXT) { /* still has a text object? */ ReleaseWriteLock(&afs_ftf); return; } } #endif /* next do the stuff that need not check for deadlock problems */ mpurge(vp); /* finally, record that we've done it */ hset(vp->flushDV, fdv); ReleaseWriteLock(&afs_ftf); }