/*===========================================================================* * lmfs_invalidate * *===========================================================================*/ void lmfs_invalidate( dev_t device /* device whose blocks are to be purged */ ) { /* Remove all the blocks belonging to some device from the cache. */ register struct buf *bp; assert(device != NO_DEV); for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++) { if (bp->lmfs_dev == device) { assert(bp->data); assert(bp->lmfs_bytes > 0); munmap_t(bp->data, bp->lmfs_bytes); bp->lmfs_dev = NO_DEV; bp->lmfs_bytes = 0; bp->data = NULL; } } /* Clear the cache even if VM caching is disabled for the file system: * caching may be disabled as side effect of an error, leaving blocks behind * in the actual VM cache. */ vm_clear_cache(device); }
/*===========================================================================* * lmfs_buf_pool * *===========================================================================*/ void lmfs_buf_pool(int new_nr_bufs) { /* Initialize the buffer pool. */ register struct buf *bp; assert(new_nr_bufs >= MINBUFS); if(nr_bufs > 0) { assert(buf); lmfs_flushall(); for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++) { if(bp->data) { assert(bp->lmfs_bytes > 0); munmap_t(bp->data, bp->lmfs_bytes); } } } if(buf) free(buf); if(!(buf = calloc(sizeof(buf[0]), new_nr_bufs))) panic("couldn't allocate buf list (%d)", new_nr_bufs); if(buf_hash) free(buf_hash); if(!(buf_hash = calloc(sizeof(buf_hash[0]), new_nr_bufs))) panic("couldn't allocate buf hash list (%d)", new_nr_bufs); nr_bufs = new_nr_bufs; bufs_in_use = 0; front = &buf[0]; rear = &buf[nr_bufs - 1]; for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++) { bp->lmfs_blocknr = NO_BLOCK; bp->lmfs_dev = NO_DEV; bp->lmfs_next = bp + 1; bp->lmfs_prev = bp - 1; bp->data = NULL; bp->lmfs_bytes = 0; } front->lmfs_prev = NULL; rear->lmfs_next = NULL; for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++) bp->lmfs_hash = bp->lmfs_next; buf_hash[0] = front; }
/*===========================================================================* * lmfs_invalidate * *===========================================================================*/ void lmfs_invalidate( dev_t device /* device whose blocks are to be purged */ ) { /* Remove all the blocks belonging to some device from the cache. */ register struct buf *bp; for (bp = &buf[0]; bp < &buf[nr_bufs]; bp++) { if (bp->lmfs_dev == device) { assert(bp->data); assert(bp->lmfs_bytes > 0); munmap_t(bp->data, bp->lmfs_bytes); bp->lmfs_dev = NO_DEV; bp->lmfs_bytes = 0; bp->data = NULL; } } vm_clear_cache(device); }
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); }