void lmfs_flushall(void) { struct buf *bp; for(bp = &buf[0]; bp < &buf[nr_bufs]; bp++) if(bp->lmfs_dev != NO_DEV && !lmfs_isclean(bp)) lmfs_flushdev(bp->lmfs_dev); }
/* * Perform a flush request on a block device, flushing and invalidating all * blocks associated with this device, both in the local cache and in VM. * This operation is called after a block device is closed and must prevent * that stale copies of blocks remain in any cache. */ void lmfs_bflush(dev_t dev) { /* First flush any dirty blocks on this device to disk. */ lmfs_flushdev(dev); /* Then purge any blocks associated with the device. */ lmfs_invalidate(dev); }
void lmfs_flushall(void) { struct buf *bp; for(bp = &buf[0]; bp < &buf[nr_bufs]; bp++) if(bp->lmfs_dev != NO_DEV && !lmfs_isclean(bp)) lmfs_flushdev(bp->lmfs_dev); /* This is the moment where it is least likely (although certainly not * impossible!) that there are buffers in use, since buffers should not * be held across file system syncs. See if we already intended to * resize the buffer cache, but couldn't. Be aware that we may be * called indirectly from within lmfs_change_blockusage(), so care must * be taken not to recurse infinitely. TODO: see if it is better to * resize the cache from here *only*, thus guaranteeing a clean cache. */ lmfs_change_blockusage(0); }
static void freeblock(struct buf *bp) { ASSERT(bp->lmfs_count == 0); /* If the block taken is dirty, make it clean by writing it to the disk. * Avoid hysteresis by flushing all other dirty blocks for the same device. */ if (bp->lmfs_dev != NO_DEV) { if (!lmfs_isclean(bp)) lmfs_flushdev(bp->lmfs_dev); assert(bp->lmfs_bytes == fs_block_size); bp->lmfs_dev = NO_DEV; } /* Fill in block's parameters and add it to the hash chain where it goes. */ MARKCLEAN(bp); /* NO_DEV blocks may be marked dirty */ if(bp->lmfs_bytes > 0) { assert(bp->data); munmap_t(bp->data, bp->lmfs_bytes); bp->lmfs_bytes = 0; bp->data = NULL; } else assert(!bp->data); }