Пример #1
0
/*{
** Name: DI_async_write -   writes page(s) to a file on disk.
**
** Description:
**	This routine was created to interface with async io routines
**	where such routines are available
**
** Inputs:
**      f                    Pointer to the DI file
**                           context needed to do I/O.
**	diop		     Pointer to dilru file context.
**      buf                  Pointer to page(s) to write.
**      page                 Value indicating page(s) to write.
**	num_of_pages	     number of pages to write
**      
** Outputs:
**      err_code             Pointer to a variable used
**                           to return operating system 
**                           errors.
**    Returns:
**          OK
**	    other errors.
**    Exceptions:
**        none
**
** Side Effects:
**        none
**
** History:
**    20-jun-1995 (amo ICL)
**	    Created.
**	01-oct-1998 (somsa01)
**	    Return DI_NODISKSPACE when we are out of disk space.
*/
static STATUS
DI_async_write(
    DI_IO	*f,
    DI_OP	*diop,
    char        *buf,
    i4	page,
    i4	num_of_pages,
    CL_ERR_DESC *err_code )
{
    STATUS	status = OK;
    int		errnum;
    CS_SCB	*scb;
    int		saved_state;
    i4	start_time, elapsed;

    /* unix variables */
    OFFSET_TYPE lseek_offset;
    int		bytes_written;
    int		bytes_to_write;

    /* 
    ** seek to place to write 
    */
    lseek_offset = (OFFSET_TYPE)f->io_bytes_per_page * (OFFSET_TYPE)page;
    bytes_to_write = (f->io_bytes_per_page * (num_of_pages));

    CSget_scb(&scb);
    if ( scb )
    {
	saved_state = scb->cs_state;
	scb->cs_state = CS_EVENT_WAIT;

	if (f->io_open_flags & DI_O_LOG_FILE_MASK)
	{
	    scb->cs_memory = CS_LIOW_MASK;
	    scb->cs_liow++;
	    Cs_srv_block.cs_wtstatistics.cs_liow_done++;
	    Cs_srv_block.cs_wtstatistics.cs_liow_waits++;
	    Cs_srv_block.cs_wtstatistics.cs_liow_kbytes
		+= bytes_to_write / 1024;
	}
	else
	{
	    scb->cs_memory = CS_DIOW_MASK;
	    scb->cs_diow++;
	    Cs_srv_block.cs_wtstatistics.cs_diow_done++;
	    Cs_srv_block.cs_wtstatistics.cs_diow_waits++;
	    Cs_srv_block.cs_wtstatistics.cs_diow_kbytes
		+= bytes_to_write / 1024;
	}
	start_time = CS_checktime();
    }

# if defined(OS_THREADS_USED) && !defined(xCL_ASYNC_IO)
    bytes_written =
 	 DI_thread_rw( O_WRONLY, diop, buf, bytes_to_write,
 	 	       lseek_offset, (long*)0, err_code);
# else /* OS_THREADS_USED */
    bytes_written =
 	 DI_aio_rw( O_WRONLY, diop, buf, bytes_to_write,
 	 	       lseek_offset, (long*)0, err_code);
# endif /* OS_THREADS_USED */
    if ( bytes_written != bytes_to_write )
    {
	SETCLERR(err_code, 0, ER_write);

	switch( err_code->errnum )
	{
	case EFBIG:
	    status = DI_BADEXTEND;
	    break;
	case ENOSPC:
	    status = DI_NODISKSPACE;
	    break;
#ifdef EDQUOTA
	case EDQUOT:
	    status = DI_EXCEED_LIMIT;
	    break;
#endif
	default:
	    if (err_code->errnum == 0)
		status = DI_ENDFILE;
	    else
		status = DI_BADWRITE;
	    break;
	}

    }

    if ( scb )
    {
	elapsed = CS_checktime() - start_time;

	scb->cs_memory &= ~(CS_DIOW_MASK | CS_LIOW_MASK);
	scb->cs_state = saved_state;
	if (f->io_open_flags & DI_O_LOG_FILE_MASK)
	    Cs_srv_block.cs_wtstatistics.cs_liow_time +=
		elapsed;
	else
	    Cs_srv_block.cs_wtstatistics.cs_diow_time +=
		elapsed;
    }

    return( status );
}
Пример #2
0
/*{
** Name: DI_inproc_read -   read page(s) from a file on disk.
**
** Description:
**	This routine was created to make DIread more readable once
**	error checking had been added. See DIread for comments.
**
** Inputs:
**      f                    Pointer to the DI file
**                           context needed to do I/O.
**	diop		     Pointer to dilru file context.
**      buf                  Pointer to page(s) to read.
**      page                 Value indicating page(s) to read.
**	num_of_pages	     number of pages to read
**      
** Outputs:
**      err_code             Pointer to a variable used
**                           to return operating system 
**                           errors.
**    Returns:
**          OK
**	    other errors.
**    Exceptions:
**        none
**
** Side Effects:
**        none
**
** History:
**    30-nov-1992 (rmuth)
**	    Created.
**    03-jun-1996 (canor01)
**	    Note in the scb that this is a DI wait.
**    14-July-1997 (schte01)
**      For those platforms that do direct i/o (where the
**      seek and the read are separate functions), do not release and
**      reaquire the semaphore on the DI_IO block. This will protect
**      against i/o being done by a different thread in between the 
**      lseek and the read.
**    14-Aug-1997 (schte01)    
**      Add xCL_DIRECT_IO as a condition to the 14-July-1997 change
**      instead of the test for !xCL_ASYNCH_IO.
**	22-Dec-1998 (jenjo02)
**	    If DI_FD_PER_THREAD is defined, call IIdio_read() instead of
**	    pread().
**  01-Apr-2004 (fanch01)
**      Add O_DIRECT support on Linux depending on the filesystem
**      properties, pagesize.  Fixups for misaligned buffers on read()
**      and write() operations.
**    13-apr-04 (toumi01)
**	Move stack variable declaration to support "standard" C compilers.
**	29-Jan-2005 (schka24)
**	    Ditch attempt to gather dior timing stats, not useful in
**	    the real world and generates excess syscalls on some platforms.
**	15-Mar-2006 (jenjo02)
**	    io_sem is not needed with thread affinity.
**	6-Nov-2009 (kschendel) SIR 122757
**	    Remove copy to aligned buffer, caller is supposed to do it.
*/
static STATUS
DI_inproc_read(
    DI_IO	*f,
    DI_OP	*diop,
    char        *buf,
    i4	page,
    i4	num_of_pages,
    i4	*n,
    CL_ERR_DESC *err_code )
{
    STATUS	status = OK;
    CS_SCB	*scb;
    i4		saved_state;

    /* unix variables */
    int		unix_fd;
    int		bytes_read = 0;
    int		bytes_to_read;
    OFFSET_TYPE	lseek_offset;

    /*
    ** Seek to place to read
    */
    lseek_offset  = (OFFSET_TYPE)f->io_bytes_per_page * (OFFSET_TYPE)page;

    bytes_to_read = f->io_bytes_per_page * num_of_pages;
    unix_fd = diop->di_fd;

    if (Di_backend)
    {
	CSget_scb(&scb);
	if ( scb )
	{
	    saved_state = scb->cs_state;
	    scb->cs_state = CS_EVENT_WAIT;

	    if (f->io_open_flags & DI_O_LOG_FILE_MASK)
	    {
		scb->cs_memory = CS_LIOR_MASK;
		scb->cs_lior++;
		Cs_srv_block.cs_wtstatistics.cs_lior_done++;
		Cs_srv_block.cs_wtstatistics.cs_lior_waits++;
		Cs_srv_block.cs_wtstatistics.cs_lior_kbytes
		    += bytes_to_read / 1024;
	    }
	    else
	    {
		scb->cs_memory = CS_DIOR_MASK;
		scb->cs_dior++;
		Cs_srv_block.cs_wtstatistics.cs_dior_done++;
		Cs_srv_block.cs_wtstatistics.cs_dior_waits++;
		Cs_srv_block.cs_wtstatistics.cs_dior_kbytes
		    += bytes_to_read / 1024;
	    }
	}
    }

# if defined( OS_THREADS_USED ) && (defined (xCL_NO_ATOMIC_READ_WRITE_IO))
    if ( !Di_thread_affinity && (f->io_fprop & FPROP_PRIVATE) == 0)
    {
	CS_synch_lock( &f->io_sem );
    }
# endif /* OS_THREADS_USED && xCL_NO_ATOMIC_READ_WRITE_IO */

# if defined( OS_THREADS_USED ) && (! defined (xCL_NO_ATOMIC_READ_WRITE_IO))
#ifdef LARGEFILE64
    bytes_read = pread64( unix_fd, buf, bytes_to_read, lseek_offset );
#else /* LARGEFILE64 */
    bytes_read = pread( unix_fd, buf, bytes_to_read, lseek_offset );
#endif /* LARGEFILE64 */

    if ( bytes_read != bytes_to_read )
    {
	SETCLERR(err_code, 0, ER_read);
# else /* OS_THREADS_USED */

    bytes_read = IIdio_read( unix_fd, buf, bytes_to_read,
 	    			  lseek_offset, 0, 
				  f->io_fprop,
				  err_code );

    if ( bytes_read != bytes_to_read )
    {
# endif /* OS_THREADS_USED && ! xCL_NO_ATOMIC_READ_WRITE_IO */

	if (bytes_read == -1)
	{
	    status = DI_BADREAD;
	}
	else
	{
	    status = DI_ENDFILE;
	}
    }
# if defined( OS_THREADS_USED ) && (defined (xCL_NO_ATOMIC_READ_WRITE_IO) )
    if ( !Di_thread_affinity && (f->io_fprop & FPROP_PRIVATE) == 0)
	CS_synch_unlock( &f->io_sem );
# endif /* OS_THREADS_USED && xCL_NO_ATOMIC_READ_WRITE_IO */

    if (Di_backend)
    {
	if ( scb )
	{
	    scb->cs_memory &= ~(CS_DIOR_MASK | CS_LIOR_MASK);
	    scb->cs_state = saved_state;
	}
    }

    if ( bytes_read > 0 )
	*n = bytes_read / f->io_bytes_per_page;

    return(status);
}

# if defined(OS_THREADS_USED) || defined(xCL_ASYNC_IO)
/*{
** Name: DI_async_read -   read page(s) asynchronously from a file on disk.
**
** Description:
**	This routine was created to interface with async io routines
**	where such routines are available.
**
** Inputs:
**      f                    Pointer to the DI file
**                           context needed to do I/O.
**	diop		     Pointer to dilru file context.
**      buf                  Pointer to page(s) to read.
**      page                 Value indicating page(s) to read.
**	num_of_pages	     number of pages to read
**      
** Outputs:
**      err_code             Pointer to a variable used
**                           to return operating system 
**                           errors.
**    Returns:
**          OK
**	    other errors.
**    Exceptions:
**        none
**
** Side Effects:
**        none
**
** History:
**    20-jun-1995 (amo ICL)
**	    Created.
*/
static STATUS
DI_async_read(
    DI_IO	*f,
    DI_OP	*diop,
    char        *buf,
    i4	page,
    i4	num_of_pages,
    i4	*n,
    CL_ERR_DESC *err_code )
{
    STATUS	status = OK;
    CS_SCB	*scb;
    int		saved_state;
    i4 		start_time;

    /* unix variables */
    int		bytes_read = 0;
    int		bytes_to_read;
    OFFSET_TYPE	lseek_offset;

    /*
    ** Seek to place to read
    */
    lseek_offset  = (OFFSET_TYPE)(f->io_bytes_per_page) * (OFFSET_TYPE)(page);
    bytes_to_read = f->io_bytes_per_page * num_of_pages;

    CSget_scb(&scb);
    if ( scb )
    {
	saved_state = scb->cs_state;
	scb->cs_state = CS_EVENT_WAIT;

	if (f->io_open_flags & DI_O_LOG_FILE_MASK)
	{
	    scb->cs_memory = CS_LIOR_MASK;
	    scb->cs_lior++;
	    Cs_srv_block.cs_wtstatistics.cs_lior_done++;
	    Cs_srv_block.cs_wtstatistics.cs_lior_waits++;
	    Cs_srv_block.cs_wtstatistics.cs_lior_kbytes
		+= bytes_to_read / 1024;
	}
	else
	{
	    scb->cs_memory = CS_DIOR_MASK;
	    scb->cs_dior++;
	    Cs_srv_block.cs_wtstatistics.cs_dior_done++;
	    Cs_srv_block.cs_wtstatistics.cs_dior_waits++;
	    Cs_srv_block.cs_wtstatistics.cs_dior_kbytes
		+= bytes_to_read / 1024;
	}
	/* Clock the read */
	start_time = CS_checktime();
    }

# if defined(OS_THREADS_USED) && !defined(xCL_ASYNC_IO)
    bytes_read = DI_thread_rw( O_RDONLY, diop, buf, bytes_to_read,
 	    			      lseek_offset, NULL, err_code);
# else /* OS_THREADS_USED */
    bytes_read = DI_aio_rw( O_RDONLY, diop, buf, bytes_to_read,
 	    			  lseek_offset, NULL, err_code);
# endif /* OS_THREADS_USED */
    if ( bytes_read != bytes_to_read )
    {
	SETCLERR(err_code, 0, ER_read);

	if (bytes_read == -1)
	{
	    status = DI_BADREAD;
	}
	else
	{
	    status = DI_ENDFILE;
	}
    }

    if ( scb )
    {
	scb->cs_memory &= ~(CS_DIOR_MASK | CS_LIOR_MASK);
	scb->cs_state = saved_state;
	if (f->io_open_flags & DI_O_LOG_FILE_MASK)
	    Cs_srv_block.cs_wtstatistics.cs_lior_time 
		+= CS_checktime() - start_time;
	else
	    Cs_srv_block.cs_wtstatistics.cs_dior_time
		+= CS_checktime() - start_time;
    }

    if ( bytes_read > 0 )
	*n = bytes_read / f->io_bytes_per_page;

    return(status);
}