void alfs_default_buffer_flushEntry (buffer_t *entry) { /* and unmap the block from our address space */ /* printf ("flushEntry: dev %d, inodeNum %x, block %d, diskBlock %d, buffer %p\n", entry->header.dev, entry->header.inodeNum, entry->header.block, entry->header.diskBlock, entry->buffer); */ exos_bufcache_unmap (entry->header.dev, entry->header.diskBlock, entry->buffer); }
void * exos_bufcache_map (struct bc_entry *bc_entry, u32 dev, u32 blk, u_int writeable) { int ret; u_int vaddr; if (bc_entry == NULL) { bc_entry = __bc_lookup (dev, blk); if (bc_entry == NULL) { return (NULL); } } vaddr = BUFCACHE_ADDR (bc_entry->buf_ppn); if (writeable) { writeable = PG_W; } ret = _exos_self_insert_pte (CAP_ROOT, ppnf2pte(bc_entry->buf_ppn, PG_P | PG_U | writeable | PG_SHARED), (u_int)vaddr, ESIP_DONTPAGE, &__sysinfo.si_pxn[bc_entry->buf_dev]); if ((bc_entry->buf_ppn != BUFCACHE_PGNO(vaddr)) || (bc_entry->buf_state == BC_EMPTY) || (bc_entry->buf_blk != blk) || (bc_entry->buf_dev != dev) || (bc_entry->buf_ppn != (va2ppn(vaddr)))) { kprintf ("buf_state %d, buf_blk %d, diskBlock %d, buf_dev %d, dev %d\n", bc_entry->buf_state, bc_entry->buf_blk, blk, bc_entry->buf_dev, dev); kprintf ("buf_ppn %d, expected %d\n", bc_entry->buf_ppn, va2ppn(vaddr)); kprintf ("gotcha: lost race detected (and handled) in " "exos_bufcache_map\n"); exos_bufcache_unmap (dev, blk, (void *)vaddr); vaddr = 0; } else if (ret != 0) { kprintf ("exos_bufcache_map: _exos_self_insert_pte failed (ret %d, " "vaddr %x, ppn %d)\n", ret, vaddr, bc_entry->buf_ppn); assert (ret == 0); } return ((void *) vaddr); }
void alfs_default_buffer_writeBack (buffer_t *entry, int async) { int ret; block_num_t diskBlock = entry->header.diskBlock; #ifdef USE_BC_DIRTY struct bc_entry *tmp; #else buffer_t *tmp; #endif int contig = 1; /* printf("alfs_buffer_writeBack: inodeNum %x, block %d, diskBlock %d\n", entry->header.inodeNum, entry->header.block, diskBlock); */ if (entry->bc_entry->buf_tainted) { if (async) { int ret = exos_bufcache_setDirty (entry->header.dev, entry->header.diskBlock, 1); assert (ret == 0); } else { kprintf ("Explicitly trying to initiate a write on a tainted block!! (inodeNum %d, block %d, buf_dirty %d, buf_tainted %d\n", entry->header.inodeNum, entry->header.block, entry->bc_entry->buf_dirty, entry->bc_entry->buf_tainted); } } /* GROK -- case of not-yet-alloced space is not handled! */ assert (diskBlock > 0); entry->buf.b_resid = 0; alfs_diskwrites++; assert ((entry->bc_entry->buf_blk == entry->header.diskBlock) || (entry->header.block == 0)); #ifdef NOGATHER #define MAXCONTIG 1 #else #define MAXCONTIG 16 #endif #ifdef USE_BC_DIRTY while ((contig < MAXCONTIG) && ((tmp = exos_bufcache_lookup (entry->header.dev, (diskBlock + contig))) != NULL) && (tmp->buf_dirty) && (!tmp->buf_tainted)) { #else while ((contig < MAXCONTIG) && ((tmp = (buffer_t *) alfs_buffertab_findDiskBlock (alfs_localCache, entry->header.dev, (diskBlock + contig))) != NULL) && (tmp->inUse == 0) && (tmp->flags & BUFFER_DIRTY) && (!tmp->bc_entry->buf_tainted)) { tmp->flags &= ~BUFFER_DIRTY; #endif contig++; } #ifdef USE_BC_DIRTY while ((contig < MAXCONTIG) && ((tmp = exos_bufcache_lookup(entry->header.dev, (diskBlock - 1))) != NULL) && (tmp->buf_dirty) && (!tmp->buf_tainted)) { #else while ((contig < MAXCONTIG) && ((tmp = (buffer_t *) alfs_buffertab_findDiskBlock (alfs_localCache, entry->header.dev, (diskBlock - 1))) != NULL) && (tmp->inUse == 0) && (tmp->flags & BUFFER_DIRTY) && (!tmp->bc_entry->buf_tainted)) { tmp->flags &= ~BUFFER_DIRTY; #endif contig++; diskBlock--; } if ((ret = exos_bufcache_initwrite (entry->bc_entry->buf_dev, diskBlock, contig, ((!async) ? &entry->buf.b_resid : NULL))) != 0) { kprintf ("default_writeBack: bc_write_dirty_bufs failed (ret %d, dev %d, blk %d, contig %d)\n", ret, entry->bc_entry->buf_dev, entry->bc_entry->buf_blk, contig); #ifdef USE_BC_DIRTY printf ("this can legally happen now...\n"); #endif assert (0); } if (!async) { exos_bufcache_waitforio (entry->bc_entry); } else { entry->buf.b_resid = -1; } } void ALFS_DISK_READ (struct buf *buf, char *memaddr, uint fsdev, uint blkno) { struct bc_entry *bc_entry; restart: if ((bc_entry = exos_bufcache_lookup(fsdev, blkno)) != NULL) { char *contents = exos_bufcache_map (bc_entry, fsdev, blkno, 0); if (contents == NULL) { goto restart; } exos_bufcache_waitforio (bc_entry); bcopy (contents, memaddr, BLOCK_SIZE); exos_bufcache_unmap (fsdev, blkno, contents); } else { exos_bufcache_initfill (fsdev, blkno, 1, NULL); goto restart; } } void ALFS_DISK_WRITE (struct buf *buf, char *memaddr, uint fsdev, uint blkno) { struct bc_entry *bc_entry; restart: if ((bc_entry = exos_bufcache_lookup(fsdev, blkno)) != NULL) { char *contents = exos_bufcache_map (bc_entry, fsdev, blkno, 1); if (contents == NULL) { goto restart; } exos_bufcache_waitforio (bc_entry); bcopy (memaddr, contents, BLOCK_SIZE); exos_bufcache_setDirty (fsdev, blkno, 1); exos_bufcache_initwrite (fsdev, blkno, 1, NULL); exos_bufcache_unmap (fsdev, blkno, contents); } else { exos_bufcache_alloc (fsdev, blkno, 0, 1, 0); goto restart; } } void alfs_defaultcache_moveblock (uint dev, uint oldblock, uint newblock) { struct Xn_xtnt src, dst; #if 0 int ret; #endif src.xtnt_block = oldblock; src.xtnt_size = 1; dst.xtnt_block = newblock; dst.xtnt_size = 1; assert (0); #if 0 if ((ret = sys_bc_move (&__sysinfo.si_pxn[dev], CAP_ROOT, 0, &src, &__sysinfo.si_pxn[dev], CAP_ROOT, 0, &dst, 1)) != 0) { printf ("cffs_alloc_doCollocation: bc_move failed (ret %d, oldblock %d, newblock %d)\n", ret, oldblock, newblock); assert (0); } #endif }