示例#1
0
/*
 * _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);
   }
}
示例#2
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 );
}