/* * _cca_sync_page * * Flush a cache page to the file. */ _cca_sync_page( struct cca_f *cca_info, struct cca_buf *cubuf, struct ffsw *stat /* pointer to status return word */ ) { int i; int ret; int partial_dirty; off_t file_byte_pos; struct fdinfo *llfio; file_byte_pos = cubuf->file_page.parts.page_number * cca_info->byte_per_pg; llfio = cca_info->nextfio; if(cubuf->sw.rw_mode == FFSW_WRITING ) { CCAWAITIO(cubuf->sw,stat,ret); if(ret==ERR)return(ERR); } partial_dirty = FALSE; for(i=0;i<cca_info->dirty_sectwds;i++) { if( cubuf->unsynced_sectors[i] != cca_info->dirty_sectors_check[i] ) { partial_dirty = TRUE; break; } } /* * If the page is partially valid, call _cca_wrabuf to flush the dirty * valid sectors and then call _cca_rdabuf to read back the entire page. * * (Why don't we just pre-read the invalid sectors and defer the syncing?? * this is done for writes, so the page is about to become dirty again...) */ if( partial_dirty ) { if( cubuf->sw.llfio ) { CCAWAITIO(cubuf->sw,stat,ret); if(ret==ERR) return(ERR); } ret = _cca_wrabuf(cca_info, llfio, cubuf, cca_info->byte_per_pg , file_byte_pos , 'a', stat); if( ret == ERR ) return( ERR ); if( cubuf->sw.llfio ) { CCAWAITIO(cubuf->sw,stat,ret); if(ret==ERR) return(ERR); } ret = _cca_rdabuf(cca_info, llfio, cubuf, cca_info->byte_per_pg , file_byte_pos , 's' , stat); if( ret == ERR ) return( ERR ); cubuf->pre_init = TRUE; return(1); } else { cubuf->pre_init = TRUE; return(0); } }
/* * _cca_flush * * Flush all dirty buffers to the underlying layer. * * Return value: 0 on success. * -1 on failure. */ int _cca_flush( struct fdinfo *fio, struct ffsw *stat ) { int i, nb, bs, ret; int errv; struct cca_f *cca_info; struct cca_buf *cbufs; off_t file_byte_pos; struct fdinfo *llfio; errv = 0; cca_info = (struct cca_f *)fio->lyr_info; nb = cca_info->nbufs; bs = cca_info->bsize; llfio = fio->fioptr; /* * Loop once to start the flush of each dirty buffer. Then loop a * second time to wait for the completions of all buffer flushes. */ cbufs = cca_info->bufs; for (i=0; i<nb; i++) { if( cbufs[i].file_page.parts.file_number != cca_info->file_number ) continue; if( cca_info->optflags.scr == FALSE ) { if( cbufs[i].flags & CCA_DIRTY ) { if( cbufs[i].sw.llfio ) { CCAWAITIO(cbufs[i].sw,stat,ret); if (ret == ERR) errv = errv ? errv : stat->sw_error; } file_byte_pos = cbufs[i].file_page.parts.page_number * cca_info->byte_per_pg; ret = _cca_wrabuf( cca_info, llfio, &cbufs[i], BITS2BYTES(bs), file_byte_pos, 'a', /*asynchronous*/ stat); if (ret == ERR) errv = errv ? errv : stat->sw_error; } } } for (i=0; i<nb; i++) /* wait for those still doing any I/O */ { if(cbufs[i].sw.file_page.parts.file_number == cca_info->file_number ) { CCAWAITIO(cbufs[i].sw,stat,ret); if (ret == ERR) errv = errv ? errv : stat->sw_error; } } if (errv) { ERETURN(stat, errv, 0); } ret = XRCALL(llfio,flushrtn) llfio, stat); return( ret ); }