/*{ ** 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 ); }
/*{ ** 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); }