|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Library for Posix async read operations with hints.
|
|
Packit |
577717 |
* Author: Don Capps
|
|
Packit |
577717 |
* Company: Iozone
|
|
Packit |
577717 |
* Date: 4/24/1998
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Two models are supported. First model is a replacement for read() where the async
|
|
Packit |
577717 |
* operations are performed and the requested data is bcopy()-ed back into the users
|
|
Packit |
577717 |
* buffer. The second model is a new version of read() where the caller does not
|
|
Packit |
577717 |
* supply the address of the buffer but instead is returned an address to the
|
|
Packit |
577717 |
* location of the data. The second model eliminates a bcopy from the path.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* To use model #1:
|
|
Packit |
577717 |
* 1. Call async_init(&pointer_on_stack,fd,direct_flag);
|
|
Packit |
577717 |
* The fd is the file descriptor for the async operations.
|
|
Packit |
577717 |
* The direct_flag sets VX_DIRECT
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* 2. Call async_read(gc, fd, ubuffer, offset, size, stride, max, depth)
|
|
Packit |
577717 |
* Where:
|
|
Packit |
577717 |
* gc ............ is the pointer on the stack
|
|
Packit |
577717 |
* fd ............ is the file descriptor
|
|
Packit |
577717 |
* ubuffer ....... is the address of the user buffer.
|
|
Packit |
577717 |
* offset ........ is the offset in the file to begin reading
|
|
Packit |
577717 |
* size .......... is the size of the transfer.
|
|
Packit |
577717 |
* stride ........ is the distance, in size units, to space the async reads.
|
|
Packit |
577717 |
* max ........... is the max size of the file to be read.
|
|
Packit |
577717 |
* depth ......... is the number of async operations to perform.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* 3. Call end_async(gc) when finished.
|
|
Packit |
577717 |
* Where:
|
|
Packit |
577717 |
* gc ............ is the pointer on the stack.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* To use model #2:
|
|
Packit |
577717 |
* 1. Call async_init(&pointer_on_stack,fd,direct_flag);
|
|
Packit |
577717 |
* The fd is the file descriptor for the async operations.
|
|
Packit |
577717 |
* The direct_flag sets VX_DIRECT
|
|
Packit |
577717 |
* 2. Call async_read(gc, fd, &ubuffer, offset, size, stride, max, depth)
|
|
Packit |
577717 |
* Where:
|
|
Packit |
577717 |
* gc ............ is the pointer on the stack
|
|
Packit |
577717 |
* fd ............ is the file descriptor
|
|
Packit |
577717 |
* ubuffer ....... is the address of a pointer that will be filled in
|
|
Packit |
577717 |
* by the async library.
|
|
Packit |
577717 |
* offset ........ is the offset in the file to begin reading
|
|
Packit |
577717 |
* size .......... is the size of the transfer.
|
|
Packit |
577717 |
* stride ........ is the distance, in size units, to space the async reads.
|
|
Packit |
577717 |
* max ........... is the max size of the file to be read.
|
|
Packit |
577717 |
* depth ......... is the number of async operations to perform.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* 3. Call async_release(gc) when finished with the data that was returned.
|
|
Packit |
577717 |
* This allows the async library to reuse the memory that was filled in
|
|
Packit |
577717 |
* and returned to the user.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* 4. Call end_async(gc) when finished.
|
|
Packit |
577717 |
* Where:
|
|
Packit |
577717 |
* gc ............ is the pointer on the stack.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* To use model #1: (WRITES)
|
|
Packit |
577717 |
* 1. Call async_init(&pointer_on_stack,fd,direct_flag);
|
|
Packit |
577717 |
* The fd is the file descriptor for the async operations.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* 2. Call async_write(gc, fd, ubuffer, size, offset, depth)
|
|
Packit |
577717 |
* Where:
|
|
Packit |
577717 |
* gc ............ is the pointer on the stack
|
|
Packit |
577717 |
* fd ............ is the file descriptor
|
|
Packit |
577717 |
* ubuffer ....... is the address of the user buffer.
|
|
Packit |
577717 |
* size .......... is the size of the transfer.
|
|
Packit |
577717 |
* offset ........ is the offset in the file to begin reading
|
|
Packit |
577717 |
* depth ......... is the number of async operations to perform.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* 4. Call end_async(gc) when finished.
|
|
Packit |
577717 |
* Where:
|
|
Packit |
577717 |
* gc ............ is the pointer on the stack.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Notes:
|
|
Packit |
577717 |
* The intended use is to replace calls to read() with calls to
|
|
Packit |
577717 |
* async_read() and allow the user to make suggestions on
|
|
Packit |
577717 |
* what kind of async read-ahead would be nice to have.
|
|
Packit |
577717 |
* The first transfer requested is guarenteed to be complete
|
|
Packit |
577717 |
* before returning to the caller. The async operations will
|
|
Packit |
577717 |
* be started and will also be guarenteed to have completed
|
|
Packit |
577717 |
* if the next call specifies its first request to be one
|
|
Packit |
577717 |
* that was previously performed with an async operation.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The async_read_no_copy() function allows the async operations
|
|
Packit |
577717 |
* to return the data to the user and not have to perform
|
|
Packit |
577717 |
* a bcopy of the data back into the user specified buffer
|
|
Packit |
577717 |
* location. This model is faster but assumes that the user
|
|
Packit |
577717 |
* application has been modified to work with this model.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The async_write() is intended to enhance the performance of
|
|
Packit |
577717 |
* initial writes to a file. This is the slowest case in the write
|
|
Packit |
577717 |
* path as it must perform meta-data allocations and wait.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <sys/types.h>
|
|
Packit |
577717 |
#include <aio.h>
|
|
Packit |
577717 |
#if defined(solaris) || defined(linux) || defined(SCO_Unixware_gcc)
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
#include <sys/timers.h>
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#include <sys/errno.h>
|
|
Packit |
577717 |
#include <unistd.h>
|
|
Packit |
577717 |
#ifndef bsd4_4
|
|
Packit |
577717 |
#include <malloc.h>
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#ifdef VXFS
|
|
Packit |
577717 |
#include <sys/fs/vx_ioctl.h>
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if defined(OSFV5) || defined(linux)
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if defined(linux)
|
|
Packit |
577717 |
#include <unistd.h>
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if (defined(solaris) && defined(__LP64__)) || defined(__s390x__) || defined(FreeBSD)
|
|
Packit |
577717 |
/* If we are building for 64-bit Solaris, all functions that return pointers
|
|
Packit |
577717 |
* must be declared before they are used; otherwise the compiler will assume
|
|
Packit |
577717 |
* that they return ints and the top 32 bits of the pointer will be lost,
|
|
Packit |
577717 |
* causing segmentation faults. The following includes take care of this.
|
|
Packit |
577717 |
* It should be safe to add these for all other OSs too, but we're only
|
|
Packit |
577717 |
* doing it for Solaris now in case another OS turns out to be a special case.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#include <strings.h> /* For the BSD string functions */
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void mbcopy(char *source, char *dest, size_t len);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if !defined(solaris) && !defined(off64_t) && !defined(_OFF64_T) && !defined(__off64_t_defined) && !defined(SCO_Unixware_gcc)
|
|
Packit |
577717 |
typedef long long off64_t;
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#if defined(OSFV5)
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
extern long long page_size;
|
|
Packit |
577717 |
extern int one;
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Internal cache entrys. Each entry on the global
|
|
Packit |
577717 |
* cache, pointed to by async_init(gc) will be of
|
|
Packit |
577717 |
* this structure type.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
char version[] = "Libasync Version $Revision$";
|
|
Packit |
577717 |
struct cache_ent {
|
|
Packit |
577717 |
struct aiocb myaiocb; /* For use in small file mode */
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#if defined(__CrayX1__)
|
|
Packit |
577717 |
aiocb64_t myaiocb64; /* For use in large file mode */
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
struct aiocb64 myaiocb64; /* For use in large file mode */
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
long long fd; /* File descriptor */
|
|
Packit |
577717 |
long long size; /* Size of the transfer */
|
|
Packit |
577717 |
struct cache_ent *forward; /* link to next element on cache list */
|
|
Packit |
577717 |
struct cache_ent *back; /* link to previous element on the cache list */
|
|
Packit |
577717 |
long long direct; /* flag to indicate if the buffer should be */
|
|
Packit |
577717 |
/* de-allocated by library */
|
|
Packit |
577717 |
char *real_address; /* Real address to free */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
volatile void *oldbuf; /* Used for firewall to prevent in flight */
|
|
Packit |
577717 |
/* accidents */
|
|
Packit |
577717 |
int oldfd; /* Used for firewall to prevent in flight */
|
|
Packit |
577717 |
/* accidents */
|
|
Packit |
577717 |
size_t oldsize; /* Used for firewall to prevent in flight */
|
|
Packit |
577717 |
/* accidents */
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Head of the cache list
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
struct cache {
|
|
Packit |
577717 |
struct cache_ent *head; /* Head of cache list */
|
|
Packit |
577717 |
struct cache_ent *tail; /* tail of cache list */
|
|
Packit |
577717 |
struct cache_ent *inuse_head; /* head of in-use list */
|
|
Packit |
577717 |
long long count; /* How many elements on the cache list */
|
|
Packit |
577717 |
struct cache_ent *w_head; /* Head of cache list */
|
|
Packit |
577717 |
struct cache_ent *w_tail; /* tail of cache list */
|
|
Packit |
577717 |
long long w_count; /* How many elements on the write list */
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
long long max_depth;
|
|
Packit |
577717 |
extern int errno;
|
|
Packit |
577717 |
struct cache_ent *alloc_cache();
|
|
Packit |
577717 |
struct cache_ent *incache();
|
|
Packit |
577717 |
void async_init();
|
|
Packit |
577717 |
void end_async();
|
|
Packit |
577717 |
int async_suspend();
|
|
Packit |
577717 |
int async_read();
|
|
Packit |
577717 |
void takeoff_cache();
|
|
Packit |
577717 |
void del_cache();
|
|
Packit |
577717 |
void async_release();
|
|
Packit |
577717 |
void putoninuse();
|
|
Packit |
577717 |
void takeoffinuse();
|
|
Packit |
577717 |
struct cache_ent *allocate_write_buffer();
|
|
Packit |
577717 |
size_t async_write();
|
|
Packit |
577717 |
void async_wait_for_write();
|
|
Packit |
577717 |
void async_put_on_write_queue();
|
|
Packit |
577717 |
void async_write_finish();
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* On Solaris _LP64 will be defined by <sys/types.h> if we're compiling
|
|
Packit |
577717 |
* as a 64-bit binary. Make sure that __LP64__ gets defined in this case,
|
|
Packit |
577717 |
* too -- it should be defined on the compiler command line, but let's
|
|
Packit |
577717 |
* not rely on this.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#if defined(_LP64)
|
|
Packit |
577717 |
#if !defined(__LP64__)
|
|
Packit |
577717 |
#define __LP64__
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/***********************************************/
|
|
Packit |
577717 |
/* Initialization routine to setup the library */
|
|
Packit |
577717 |
/***********************************************/
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
async_init(gc,fd,flag)
|
|
Packit |
577717 |
struct cache **gc;
|
|
Packit |
577717 |
int fd;
|
|
Packit |
577717 |
int flag;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef VXFS
|
|
Packit |
577717 |
if(flag)
|
|
Packit |
577717 |
ioctl(fd,VX_SETCACHE,VX_DIRECT);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(*gc)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("Warning calling async_init two times ?\n");
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
*gc=(struct cache *)malloc((size_t)sizeof(struct cache));
|
|
Packit |
577717 |
if(*gc == 0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("Malloc failed\n");
|
|
Packit |
577717 |
exit(174);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
bzero(*gc,sizeof(struct cache));
|
|
Packit |
577717 |
#if defined(__AIX__) || defined(SCO_Unixware_gcc)
|
|
Packit |
577717 |
max_depth=500;
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
max_depth=sysconf(_SC_AIO_MAX);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/***********************************************/
|
|
Packit |
577717 |
/* Tear down routine to shutdown the library */
|
|
Packit |
577717 |
/***********************************************/
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
end_async(gc)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
del_cache(gc);
|
|
Packit |
577717 |
async_write_finish(gc);
|
|
Packit |
577717 |
free((void *)gc);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/***********************************************/
|
|
Packit |
577717 |
/* Wait for a request to finish */
|
|
Packit |
577717 |
/***********************************************/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
async_suspend(struct cache_ent *ce)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
const struct aiocb * const cblist[1] = {&ce->myaiocb};
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
const struct aiocb64 * const cblist[1] = {&ce->myaiocb64};
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
const struct aiocb * const cblist[1] = {&ce->myaiocb};
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
return aio_suspend(cblist, 1, NULL);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
return aio_suspend64(cblist, 1, NULL);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
return aio_suspend(cblist, 1, NULL);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*************************************************************************
|
|
Packit |
577717 |
* This routine is a generic async reader assist funtion. It takes
|
|
Packit |
577717 |
* the same calling parameters as read() but also extends the
|
|
Packit |
577717 |
* interface to include:
|
|
Packit |
577717 |
* stride ..... For the async reads, what is the distance, in size units,
|
|
Packit |
577717 |
* to space the reads. Note: Stride of 0 indicates that
|
|
Packit |
577717 |
* you do not want any read-ahead.
|
|
Packit |
577717 |
* max ..... What is the maximum file offset for this operation.
|
|
Packit |
577717 |
* depth ..... How much read-ahead do you want.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* The calls to this will guarentee to complete the read() operation
|
|
Packit |
577717 |
* before returning to the caller. The completion may occur in two
|
|
Packit |
577717 |
* ways. First the operation may be completed by calling aio_read()
|
|
Packit |
577717 |
* and then waiting for it to complete. Second the operation may be
|
|
Packit |
577717 |
* completed by copying the data from a cache of previously completed
|
|
Packit |
577717 |
* async operations.
|
|
Packit |
577717 |
* In the event the read to be satisfied is not in the cache then a
|
|
Packit |
577717 |
* series of async operations will be scheduled and then the first
|
|
Packit |
577717 |
* async read will be completed. In the event that the read() can be
|
|
Packit |
577717 |
* satisfied from the cache then the data is copied back to the
|
|
Packit |
577717 |
* user buffer and a series of async reads will be initiated. If a
|
|
Packit |
577717 |
* read is issued and the cache contains data and the read can not
|
|
Packit |
577717 |
* be satisfied from the cache, then the cache is discarded, and
|
|
Packit |
577717 |
* a new cache is constructed.
|
|
Packit |
577717 |
* Note: All operations are aio_read(). The series will be issued
|
|
Packit |
577717 |
* as asyncs in the order requested. After all are in flight
|
|
Packit |
577717 |
* then the code will wait for the manditory first read.
|
|
Packit |
577717 |
*************************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
async_read(gc, fd, ubuffer, offset, size, stride, max, depth)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
long long fd;
|
|
Packit |
577717 |
char *ubuffer;
|
|
Packit |
577717 |
off64_t offset;
|
|
Packit |
577717 |
long long size;
|
|
Packit |
577717 |
long long stride;
|
|
Packit |
577717 |
off64_t max;
|
|
Packit |
577717 |
long long depth;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
off64_t a_offset,r_offset;
|
|
Packit |
577717 |
long long a_size;
|
|
Packit |
577717 |
struct cache_ent *ce,*first_ce=0;
|
|
Packit |
577717 |
long long i;
|
|
Packit |
577717 |
ssize_t retval=0;
|
|
Packit |
577717 |
ssize_t ret;
|
|
Packit |
577717 |
long long start = 0;
|
|
Packit |
577717 |
long long del_read=0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
a_offset=offset;
|
|
Packit |
577717 |
a_size = size;
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Check to see if it can be completed from the cache
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if((ce=(struct cache_ent *)incache(gc,fd,offset,size)))
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret=aio_error64(&ce->myaiocb64))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("aio_error 1: ret %d %d\n",ret,errno);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
retval=aio_return(&ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
#if defined(__CrayX1__)
|
|
Packit |
577717 |
retval=aio_return64((aiocb64_t *)&ce->myaiocb64);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
retval=aio_return64((struct aiocb64 *)&ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
retval=aio_return(&ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(retval > 0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
mbcopy((char *)ce->myaiocb.aio_buf,(char *)ubuffer,(size_t)retval);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
mbcopy((char *)ce->myaiocb64.aio_buf,(char *)ubuffer,(size_t)retval);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
mbcopy((char *)ce->myaiocb.aio_buf,(char *)ubuffer,(size_t)retval);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
if(retval < ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(retval < ce->myaiocb64.aio_nbytes)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(retval < ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("aio_return error1: ret %d %d\n",retval,errno);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
printf("aio_return error1: fd %d offset %ld buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
(long)(ce->myaiocb.aio_buf),
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes,
|
|
Packit |
577717 |
ce->myaiocb.aio_lio_opcode
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("aio_return error1: fd %d offset %lld buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
ce->myaiocb64.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb64.aio_offset,
|
|
Packit |
577717 |
(long)(ce->myaiocb64.aio_buf),
|
|
Packit |
577717 |
ce->myaiocb64.aio_nbytes,
|
|
Packit |
577717 |
ce->myaiocb64.aio_lio_opcode
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("aio_return error1: fd %d offset %d buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
(long)(ce->myaiocb.aio_buf),
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes,
|
|
Packit |
577717 |
ce->myaiocb.aio_lio_opcode
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
ce->direct=0;
|
|
Packit |
577717 |
takeoff_cache(gc,ce);
|
|
Packit |
577717 |
}else
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Clear the cache and issue the first request async()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
del_cache(gc);
|
|
Packit |
577717 |
del_read++;
|
|
Packit |
577717 |
first_ce=alloc_cache(gc,fd,offset,size,(long long)LIO_READ);
|
|
Packit |
577717 |
again:
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
ret=aio_read(&first_ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ret=aio_read64(&first_ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ret=aio_read(&first_ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret!=0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if(errno==EAGAIN)
|
|
Packit |
577717 |
goto again;
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
printf("error returned from aio_read(). Ret %d errno %d\n",ret,errno);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(stride==0) /* User does not want read-ahead */
|
|
Packit |
577717 |
goto out;
|
|
Packit |
577717 |
if(a_offset<0) /* Before beginning of file */
|
|
Packit |
577717 |
goto out;
|
|
Packit |
577717 |
if(a_offset+size>max) /* After end of file */
|
|
Packit |
577717 |
goto out;
|
|
Packit |
577717 |
if(depth >=(max_depth-1))
|
|
Packit |
577717 |
depth=max_depth-1;
|
|
Packit |
577717 |
if(depth==0)
|
|
Packit |
577717 |
goto out;
|
|
Packit |
577717 |
if(gc->count > 1)
|
|
Packit |
577717 |
start=depth-1;
|
|
Packit |
577717 |
for(i=start;i
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
r_offset=a_offset+((i+1)*(stride*a_size));
|
|
Packit |
577717 |
if(r_offset<0)
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
if(r_offset+size > max)
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
if((ce=incache(gc,fd,r_offset,a_size)))
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
ce=alloc_cache(gc,fd,r_offset,a_size,(long long)LIO_READ);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
ret=aio_read(&ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ret=aio_read64(&ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ret=aio_read(&ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret!=0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
takeoff_cache(gc,ce);
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
out:
|
|
Packit |
577717 |
if(del_read) /* Wait for the first read to complete */
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
while((ret=aio_error(&first_ce->myaiocb))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(first_ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret=aio_error64(&first_ce->myaiocb64))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(first_ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret=aio_error(&first_ce->myaiocb))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(first_ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret)
|
|
Packit |
577717 |
printf("aio_error 2: ret %d %d\n",ret,errno);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
retval=aio_return(&first_ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
retval=aio_return64(&first_ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
retval=aio_return(&first_ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
if(retval < first_ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(retval < first_ce->myaiocb64.aio_nbytes)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(retval < first_ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("aio_return error2: ret %d %d\n",retval,errno);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
printf("aio_return error2: fd %d offset %lld buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
first_ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
first_ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
(long)(first_ce->myaiocb.aio_buf),
|
|
Packit |
577717 |
first_ce->myaiocb.aio_nbytes,
|
|
Packit |
577717 |
first_ce->myaiocb.aio_lio_opcode
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("aio_return error2: fd %d offset %lld buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
first_ce->myaiocb64.aio_fildes,
|
|
Packit |
577717 |
first_ce->myaiocb64.aio_offset,
|
|
Packit |
577717 |
(long)(first_ce->myaiocb64.aio_buf),
|
|
Packit |
577717 |
first_ce->myaiocb64.aio_nbytes,
|
|
Packit |
577717 |
first_ce->myaiocb64.aio_lio_opcode
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("aio_return error2: fd %d offset %d buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
first_ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
first_ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
(long)(first_ce->myaiocb.aio_buf),
|
|
Packit |
577717 |
first_ce->myaiocb.aio_nbytes,
|
|
Packit |
577717 |
first_ce->myaiocb.aio_lio_opcode
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(retval > 0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
mbcopy((char *)first_ce->myaiocb.aio_buf,(char *)ubuffer,(size_t)retval);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
mbcopy((char *)first_ce->myaiocb64.aio_buf,(char *)ubuffer,(size_t)retval);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
mbcopy((char *)first_ce->myaiocb.aio_buf,(char *)ubuffer,(size_t)retval);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
first_ce->direct=0;
|
|
Packit |
577717 |
takeoff_cache(gc,first_ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return((int)retval);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************************************************************
|
|
Packit |
577717 |
* This routine allocates a cache_entry. It contains the
|
|
Packit |
577717 |
* aiocb block as well as linkage for use in the cache mechanism.
|
|
Packit |
577717 |
* The space allocated here will be released after the cache entry
|
|
Packit |
577717 |
* has been consumed. The routine takeoff_cache() will be called
|
|
Packit |
577717 |
* after the data has been copied to user buffer or when the
|
|
Packit |
577717 |
* cache is purged. The routine takeoff_cache() will also release
|
|
Packit |
577717 |
* all memory associated with this cache entry.
|
|
Packit |
577717 |
************************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
struct cache_ent *
|
|
Packit |
577717 |
alloc_cache(gc,fd,offset,size,op)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
long long fd,size,op;
|
|
Packit |
577717 |
off64_t offset;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct cache_ent *ce;
|
|
Packit |
577717 |
long temp;
|
|
Packit |
577717 |
ce=(struct cache_ent *)malloc((size_t)sizeof(struct cache_ent));
|
|
Packit |
577717 |
if(ce == (struct cache_ent *)0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("Malloc failed\n");
|
|
Packit |
577717 |
exit(175);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
bzero(ce,sizeof(struct cache_ent));
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes=(int)fd;
|
|
Packit |
577717 |
ce->myaiocb.aio_offset=(off64_t)offset;
|
|
Packit |
577717 |
ce->real_address = (char *)malloc((size_t)(size+page_size));
|
|
Packit |
577717 |
temp=(long)ce->real_address;
|
|
Packit |
577717 |
temp = (temp+page_size) & ~(page_size-1);
|
|
Packit |
577717 |
ce->myaiocb.aio_buf=(volatile void *)temp;
|
|
Packit |
577717 |
if(ce->myaiocb.aio_buf == 0)
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ce->myaiocb64.aio_fildes=(int)fd;
|
|
Packit |
577717 |
ce->myaiocb64.aio_offset=(off64_t)offset;
|
|
Packit |
577717 |
ce->real_address = (char *)malloc((size_t)(size+page_size));
|
|
Packit |
577717 |
temp=(long)ce->real_address;
|
|
Packit |
577717 |
temp = (temp+page_size) & ~(page_size-1);
|
|
Packit |
577717 |
ce->myaiocb64.aio_buf=(volatile void *)temp;
|
|
Packit |
577717 |
if(ce->myaiocb64.aio_buf == 0)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes=(int)fd;
|
|
Packit |
577717 |
ce->myaiocb.aio_offset=(off_t)offset;
|
|
Packit |
577717 |
ce->real_address = (char *)malloc((size_t)(size+page_size));
|
|
Packit |
577717 |
temp=(long)ce->real_address;
|
|
Packit |
577717 |
temp = (temp+page_size) & ~(page_size-1);
|
|
Packit |
577717 |
ce->myaiocb.aio_buf=(volatile void *)temp;
|
|
Packit |
577717 |
if(ce->myaiocb.aio_buf == 0)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("Malloc failed\n");
|
|
Packit |
577717 |
exit(176);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/*bzero(ce->myaiocb.aio_buf,(size_t)size);*/
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
ce->myaiocb.aio_reqprio=0;
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes=(size_t)size;
|
|
Packit |
577717 |
ce->myaiocb.aio_sigevent.sigev_notify=SIGEV_NONE;
|
|
Packit |
577717 |
ce->myaiocb.aio_lio_opcode=(int)op;
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ce->myaiocb64.aio_reqprio=0;
|
|
Packit |
577717 |
ce->myaiocb64.aio_nbytes=(size_t)size;
|
|
Packit |
577717 |
ce->myaiocb64.aio_sigevent.sigev_notify=SIGEV_NONE;
|
|
Packit |
577717 |
ce->myaiocb64.aio_lio_opcode=(int)op;
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ce->myaiocb.aio_reqprio=0;
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes=(size_t)size;
|
|
Packit |
577717 |
ce->myaiocb.aio_sigevent.sigev_notify=SIGEV_NONE;
|
|
Packit |
577717 |
ce->myaiocb.aio_lio_opcode=(int)op;
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
ce->fd=(int)fd;
|
|
Packit |
577717 |
ce->forward=0;
|
|
Packit |
577717 |
ce->back=gc->tail;
|
|
Packit |
577717 |
if(gc->tail)
|
|
Packit |
577717 |
gc->tail->forward = ce;
|
|
Packit |
577717 |
gc->tail= ce;
|
|
Packit |
577717 |
if(!gc->head)
|
|
Packit |
577717 |
gc->head=ce;
|
|
Packit |
577717 |
gc->count++;
|
|
Packit |
577717 |
return(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************************************************************
|
|
Packit |
577717 |
* This routine checks to see if the requested data is in the
|
|
Packit |
577717 |
* cache.
|
|
Packit |
577717 |
*************************************************************************/
|
|
Packit |
577717 |
struct cache_ent *
|
|
Packit |
577717 |
incache(gc,fd,offset,size)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
long long fd,size;
|
|
Packit |
577717 |
off64_t offset;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct cache_ent *move;
|
|
Packit |
577717 |
if(gc->head==0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return(0);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
move=gc->head;
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
while(move)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if((move->fd == fd) && (move->myaiocb.aio_offset==(off64_t)offset) &&
|
|
Packit |
577717 |
((size_t)size==move->myaiocb.aio_nbytes))
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return(move);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
move=move->forward;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while(move)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if((move->fd == fd) && (move->myaiocb64.aio_offset==(off64_t)offset) &&
|
|
Packit |
577717 |
((size_t)size==move->myaiocb64.aio_nbytes))
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return(move);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
move=move->forward;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while(move)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if((move->fd == fd) && (move->myaiocb.aio_offset==(off_t)offset) &&
|
|
Packit |
577717 |
((size_t)size==move->myaiocb.aio_nbytes))
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return(move);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
move=move->forward;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
return(0);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************************************************************
|
|
Packit |
577717 |
* This routine removes a specific cache entry from the cache, and
|
|
Packit |
577717 |
* releases all memory associated witht the cache entry (if not direct).
|
|
Packit |
577717 |
*************************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
takeoff_cache(gc,ce)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
struct cache_ent *ce;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct cache_ent *move;
|
|
Packit |
577717 |
long long found;
|
|
Packit |
577717 |
move=gc->head;
|
|
Packit |
577717 |
if(move==ce) /* Head of list */
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
|
|
Packit |
577717 |
gc->head=ce->forward;
|
|
Packit |
577717 |
if(gc->head)
|
|
Packit |
577717 |
gc->head->back=0;
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
gc->tail = 0;
|
|
Packit |
577717 |
if(!ce->direct)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
free((void *)(ce->real_address));
|
|
Packit |
577717 |
free((void *)ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
gc->count--;
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
found=0;
|
|
Packit |
577717 |
while(move)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if(move==ce)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if(move->forward)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
move->forward->back=move->back;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(move->back)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
move->back->forward=move->forward;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
found=1;
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
move=move->forward;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(gc->head == ce)
|
|
Packit |
577717 |
gc->tail = ce;
|
|
Packit |
577717 |
if(!found)
|
|
Packit |
577717 |
printf("Internal Error in takeoff cache\n");
|
|
Packit |
577717 |
move=gc->head;
|
|
Packit |
577717 |
if(!ce->direct)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
free((void *)(ce->real_address));
|
|
Packit |
577717 |
free((void *)ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
gc->count--;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************************************************************
|
|
Packit |
577717 |
* This routine is used to purge the entire cache. This is called when
|
|
Packit |
577717 |
* the cache contains data but the incomming read was not able to
|
|
Packit |
577717 |
* be satisfied from the cache. This indicates that the previous
|
|
Packit |
577717 |
* async read-ahead was not correct and a new pattern is emerging.
|
|
Packit |
577717 |
************************************************************************/
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
del_cache(gc)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct cache_ent *ce;
|
|
Packit |
577717 |
ssize_t ret;
|
|
Packit |
577717 |
ce=gc->head;
|
|
Packit |
577717 |
while(1)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
ce=gc->head;
|
|
Packit |
577717 |
if(ce==0)
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
while((ret = aio_cancel(0,&ce->myaiocb))==AIO_NOTCANCELED)
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret = aio_cancel64(0,&ce->myaiocb64))==AIO_NOTCANCELED)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret = aio_cancel(0,&ce->myaiocb))==AIO_NOTCANCELED)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
ret = aio_return(&ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ret = aio_return64(&ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ret = aio_return(&ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
ce->direct=0;
|
|
Packit |
577717 |
takeoff_cache(gc,ce); /* remove from cache */
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************************************************************
|
|
Packit |
577717 |
* Like its sister async_read() this function performs async I/O for
|
|
Packit |
577717 |
* all buffers but it differs in that it expects the caller to
|
|
Packit |
577717 |
* request a pointer to the data to be returned instead of handing
|
|
Packit |
577717 |
* the function a location to put the data. This will allow the
|
|
Packit |
577717 |
* async I/O to be performed and does not require any bcopy to be
|
|
Packit |
577717 |
* done to put the data back into the location specified by the caller.
|
|
Packit |
577717 |
************************************************************************/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
async_read_no_copy(gc, fd, ubuffer, offset, size, stride, max, depth)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
long long fd;
|
|
Packit |
577717 |
char **ubuffer;
|
|
Packit |
577717 |
off64_t offset;
|
|
Packit |
577717 |
long long size;
|
|
Packit |
577717 |
long long stride;
|
|
Packit |
577717 |
off64_t max;
|
|
Packit |
577717 |
long long depth;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
off64_t a_offset,r_offset;
|
|
Packit |
577717 |
long long a_size;
|
|
Packit |
577717 |
struct cache_ent *ce,*first_ce=0;
|
|
Packit |
577717 |
long long i;
|
|
Packit |
577717 |
ssize_t retval=0;
|
|
Packit |
577717 |
ssize_t ret;
|
|
Packit |
577717 |
long long del_read=0;
|
|
Packit |
577717 |
long long start=0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
a_offset=offset;
|
|
Packit |
577717 |
a_size = size;
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Check to see if it can be completed from the cache
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
if((ce=(struct cache_ent *)incache(gc,fd,offset,size)))
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret=aio_error64(&ce->myaiocb64))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret)
|
|
Packit |
577717 |
printf("aio_error 3: ret %d %d\n",ret,errno);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
if(ce->oldbuf != ce->myaiocb.aio_buf ||
|
|
Packit |
577717 |
ce->oldfd != ce->myaiocb.aio_fildes ||
|
|
Packit |
577717 |
ce->oldsize != ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(ce->oldbuf != ce->myaiocb64.aio_buf ||
|
|
Packit |
577717 |
ce->oldfd != ce->myaiocb64.aio_fildes ||
|
|
Packit |
577717 |
ce->oldsize != ce->myaiocb64.aio_nbytes)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(ce->oldbuf != ce->myaiocb.aio_buf ||
|
|
Packit |
577717 |
ce->oldfd != ce->myaiocb.aio_fildes ||
|
|
Packit |
577717 |
ce->oldsize != ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
printf("It changed in flight\n");
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
retval=aio_return(&ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
retval=aio_return64(&ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
retval=aio_return(&ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(retval > 0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
*ubuffer=(char *)ce->myaiocb.aio_buf;
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
*ubuffer=(char *)ce->myaiocb64.aio_buf;
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
*ubuffer=(char *)ce->myaiocb.aio_buf;
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
}else
|
|
Packit |
577717 |
*ubuffer=0;
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
if(retval < ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(retval < ce->myaiocb64.aio_nbytes)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(retval < ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("aio_return error4: ret %d %d\n",retval,errno);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
printf("aio_return error4: fd %d offset %lld buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
(long)(ce->myaiocb.aio_buf),
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes,
|
|
Packit |
577717 |
ce->myaiocb.aio_lio_opcode
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("aio_return error4: fd %d offset %lld buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
ce->myaiocb64.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb64.aio_offset,
|
|
Packit |
577717 |
(long)(ce->myaiocb64.aio_buf),
|
|
Packit |
577717 |
ce->myaiocb64.aio_nbytes,
|
|
Packit |
577717 |
ce->myaiocb64.aio_lio_opcode
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("aio_return error4: fd %d offset %d buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
(long)(ce->myaiocb.aio_buf),
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes,
|
|
Packit |
577717 |
ce->myaiocb.aio_lio_opcode
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
ce->direct=1;
|
|
Packit |
577717 |
takeoff_cache(gc,ce); /* do not delete buffer*/
|
|
Packit |
577717 |
putoninuse(gc,ce);
|
|
Packit |
577717 |
}else
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Clear the cache and issue the first request async()
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
del_cache(gc);
|
|
Packit |
577717 |
del_read++;
|
|
Packit |
577717 |
first_ce=alloc_cache(gc,fd,offset,size,(long long)LIO_READ); /* allocate buffer */
|
|
Packit |
577717 |
/*printf("allocated buffer/read %x offset %d\n",first_ce->myaiocb.aio_buf,offset);*/
|
|
Packit |
577717 |
again:
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
first_ce->oldbuf=first_ce->myaiocb.aio_buf;
|
|
Packit |
577717 |
first_ce->oldfd=first_ce->myaiocb.aio_fildes;
|
|
Packit |
577717 |
first_ce->oldsize=first_ce->myaiocb.aio_nbytes;
|
|
Packit |
577717 |
ret=aio_read(&first_ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
first_ce->oldbuf=first_ce->myaiocb64.aio_buf;
|
|
Packit |
577717 |
first_ce->oldfd=first_ce->myaiocb64.aio_fildes;
|
|
Packit |
577717 |
first_ce->oldsize=first_ce->myaiocb64.aio_nbytes;
|
|
Packit |
577717 |
ret=aio_read64(&first_ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
first_ce->oldbuf=first_ce->myaiocb.aio_buf;
|
|
Packit |
577717 |
first_ce->oldfd=first_ce->myaiocb.aio_fildes;
|
|
Packit |
577717 |
first_ce->oldsize=first_ce->myaiocb.aio_nbytes;
|
|
Packit |
577717 |
ret=aio_read(&first_ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret!=0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if(errno==EAGAIN)
|
|
Packit |
577717 |
goto again;
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
printf("error returned from aio_read(). Ret %d errno %d\n",ret,errno);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(stride==0) /* User does not want read-ahead */
|
|
Packit |
577717 |
goto out;
|
|
Packit |
577717 |
if(a_offset<0) /* Before beginning of file */
|
|
Packit |
577717 |
goto out;
|
|
Packit |
577717 |
if(a_offset+size>max) /* After end of file */
|
|
Packit |
577717 |
goto out;
|
|
Packit |
577717 |
if(depth >=(max_depth-1))
|
|
Packit |
577717 |
depth=max_depth-1;
|
|
Packit |
577717 |
if(depth==0)
|
|
Packit |
577717 |
goto out;
|
|
Packit |
577717 |
if(gc->count > 1)
|
|
Packit |
577717 |
start=depth-1;
|
|
Packit |
577717 |
for(i=start;i
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
r_offset=a_offset+((i+1)*(stride*a_size));
|
|
Packit |
577717 |
if(r_offset<0)
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
if(r_offset+size > max)
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
if((ce=incache(gc,fd,r_offset,a_size)))
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
ce=alloc_cache(gc,fd,r_offset,a_size,(long long)LIO_READ);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
ce->oldbuf=ce->myaiocb.aio_buf;
|
|
Packit |
577717 |
ce->oldfd=ce->myaiocb.aio_fildes;
|
|
Packit |
577717 |
ce->oldsize=ce->myaiocb.aio_nbytes;
|
|
Packit |
577717 |
ret=aio_read(&ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ce->oldbuf=ce->myaiocb64.aio_buf;
|
|
Packit |
577717 |
ce->oldfd=ce->myaiocb64.aio_fildes;
|
|
Packit |
577717 |
ce->oldsize=ce->myaiocb64.aio_nbytes;
|
|
Packit |
577717 |
ret=aio_read64(&ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ce->oldbuf=ce->myaiocb.aio_buf;
|
|
Packit |
577717 |
ce->oldfd=ce->myaiocb.aio_fildes;
|
|
Packit |
577717 |
ce->oldsize=ce->myaiocb.aio_nbytes;
|
|
Packit |
577717 |
ret=aio_read(&ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret!=0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
takeoff_cache(gc,ce);
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
out:
|
|
Packit |
577717 |
if(del_read) /* Wait for the first read to complete */
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
while((ret=aio_error(&first_ce->myaiocb))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(first_ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret=aio_error64(&first_ce->myaiocb64))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(first_ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret=aio_error(&first_ce->myaiocb))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(first_ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret)
|
|
Packit |
577717 |
printf("aio_error 4: ret %d %d\n",ret,errno);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
if(first_ce->oldbuf != first_ce->myaiocb.aio_buf ||
|
|
Packit |
577717 |
first_ce->oldfd != first_ce->myaiocb.aio_fildes ||
|
|
Packit |
577717 |
first_ce->oldsize != first_ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
printf("It changed in flight2\n");
|
|
Packit |
577717 |
retval=aio_return(&first_ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(first_ce->oldbuf != first_ce->myaiocb64.aio_buf ||
|
|
Packit |
577717 |
first_ce->oldfd != first_ce->myaiocb64.aio_fildes ||
|
|
Packit |
577717 |
first_ce->oldsize != first_ce->myaiocb64.aio_nbytes)
|
|
Packit |
577717 |
printf("It changed in flight2\n");
|
|
Packit |
577717 |
retval=aio_return64(&first_ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(first_ce->oldbuf != first_ce->myaiocb.aio_buf ||
|
|
Packit |
577717 |
first_ce->oldfd != first_ce->myaiocb.aio_fildes ||
|
|
Packit |
577717 |
first_ce->oldsize != first_ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
printf("It changed in flight2\n");
|
|
Packit |
577717 |
retval=aio_return(&first_ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
if(retval < first_ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(retval < first_ce->myaiocb64.aio_nbytes)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
if(retval < first_ce->myaiocb.aio_nbytes)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("aio_return error5: ret %d %d\n",retval,errno);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
printf("aio_return error5: fd %d offset %lld buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
first_ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
first_ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
(long)(first_ce->myaiocb.aio_buf),
|
|
Packit |
577717 |
first_ce->myaiocb.aio_nbytes,
|
|
Packit |
577717 |
first_ce->myaiocb.aio_lio_opcode
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("aio_return error5: fd %d offset %lld buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
first_ce->myaiocb64.aio_fildes,
|
|
Packit |
577717 |
first_ce->myaiocb64.aio_offset,
|
|
Packit |
577717 |
(long)(first_ce->myaiocb64.aio_buf),
|
|
Packit |
577717 |
first_ce->myaiocb64.aio_nbytes,
|
|
Packit |
577717 |
first_ce->myaiocb64.aio_lio_opcode
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("aio_return error5: fd %d offset %ld buffer %lx size %d Opcode %d\n",
|
|
Packit |
577717 |
first_ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
first_ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
(long)(first_ce->myaiocb.aio_buf),
|
|
Packit |
577717 |
first_ce->myaiocb.aio_nbytes,
|
|
Packit |
577717 |
first_ce->myaiocb.aio_lio_opcode
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(retval > 0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
*ubuffer=(char *)first_ce->myaiocb.aio_buf;
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
*ubuffer=(char *)first_ce->myaiocb64.aio_buf;
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
*ubuffer=(char *)first_ce->myaiocb.aio_buf;
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
}else
|
|
Packit |
577717 |
*ubuffer=(char *)0;
|
|
Packit |
577717 |
first_ce->direct=1; /* do not delete the buffer */
|
|
Packit |
577717 |
takeoff_cache(gc,first_ce);
|
|
Packit |
577717 |
putoninuse(gc,first_ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return((int)retval);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************************************************************
|
|
Packit |
577717 |
* The caller is now finished with the data that was provided so
|
|
Packit |
577717 |
* the library is now free to return the memory to the pool for later
|
|
Packit |
577717 |
* reuse.
|
|
Packit |
577717 |
************************************************************************/
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
async_release(gc)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
takeoffinuse(gc);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************************************************************
|
|
Packit |
577717 |
* Put the buffer on the inuse list. When the user is finished with
|
|
Packit |
577717 |
* the buffer it will call back into async_release and the items on the
|
|
Packit |
577717 |
* inuse list will be deallocated.
|
|
Packit |
577717 |
************************************************************************/
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
putoninuse(gc,entry)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
struct cache_ent *entry;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if(gc->inuse_head)
|
|
Packit |
577717 |
entry->forward=gc->inuse_head;
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
entry->forward=0;
|
|
Packit |
577717 |
gc->inuse_head=entry;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************************************************************
|
|
Packit |
577717 |
* This is called when the application is finished with the data that
|
|
Packit |
577717 |
* was provided. The memory may now be returned to the pool.
|
|
Packit |
577717 |
************************************************************************/
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
takeoffinuse(gc)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct cache_ent *ce;
|
|
Packit |
577717 |
if(gc->inuse_head==0)
|
|
Packit |
577717 |
printf("Takeoffinuse error\n");
|
|
Packit |
577717 |
ce=gc->inuse_head;
|
|
Packit |
577717 |
gc->inuse_head=gc->inuse_head->forward;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if(gc->inuse_head !=0)
|
|
Packit |
577717 |
printf("Error in take off inuse\n");
|
|
Packit |
577717 |
free((void*)(ce->real_address));
|
|
Packit |
577717 |
free(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*************************************************************************
|
|
Packit |
577717 |
* This routine is a generic async writer assist funtion. It takes
|
|
Packit |
577717 |
* the same calling parameters as write() but also extends the
|
|
Packit |
577717 |
* interface to include:
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* offset ..... offset in the file.
|
|
Packit |
577717 |
* depth ..... How much read-ahead do you want.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*************************************************************************/
|
|
Packit |
577717 |
size_t
|
|
Packit |
577717 |
async_write(gc,fd,buffer,size,offset,depth)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
long long fd,size;
|
|
Packit |
577717 |
char *buffer;
|
|
Packit |
577717 |
off64_t offset;
|
|
Packit |
577717 |
long long depth;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct cache_ent *ce;
|
|
Packit |
577717 |
size_t ret;
|
|
Packit |
577717 |
ce=allocate_write_buffer(gc,fd,offset,size,(long long)LIO_WRITE,depth,0LL,(char *)0,(char *)0);
|
|
Packit |
577717 |
ce->direct=0; /* not direct. Lib supplies buffer and must free it */
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
mbcopy(buffer,(char *)(ce->myaiocb.aio_buf),(size_t)size);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
mbcopy(buffer,(char *)(ce->myaiocb64.aio_buf),(size_t)size);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
mbcopy(buffer,(char *)(ce->myaiocb.aio_buf),(size_t)size);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
async_put_on_write_queue(gc,ce);
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
printf("asw: fd %d offset %lld, size %d\n",ce->myaiocb64.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb64.aio_offset,
|
|
Packit |
577717 |
ce->myaiocb64.aio_nbytes);
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
again:
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
ret=aio_write(&ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ret=aio_write64(&ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ret=aio_write(&ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret==-1)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if(errno==EAGAIN)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_wait_for_write(gc);
|
|
Packit |
577717 |
goto again;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(errno==0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/* Compensate for bug in async library */
|
|
Packit |
577717 |
async_wait_for_write(gc);
|
|
Packit |
577717 |
goto again;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("Error in aio_write: ret %d errno %d count %lld\n",ret,errno,gc->w_count);
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
printf("aio_write_no_copy: fd %d buffer %x offset %lld size %d\n",
|
|
Packit |
577717 |
ce->myaiocb64.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb64.aio_buf,
|
|
Packit |
577717 |
ce->myaiocb64.aio_offset,
|
|
Packit |
577717 |
ce->myaiocb64.aio_nbytes);
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
exit(177);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return((ssize_t)size);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*************************************************************************
|
|
Packit |
577717 |
* Allocate a write aiocb and write buffer of the size specified. Also
|
|
Packit |
577717 |
* put some extra buffer padding so that VX_DIRECT can do its job when
|
|
Packit |
577717 |
* needed.
|
|
Packit |
577717 |
*************************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
struct cache_ent *
|
|
Packit |
577717 |
allocate_write_buffer(gc,fd,offset,size,op,w_depth,direct,buffer,free_addr)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
long long fd,size,op;
|
|
Packit |
577717 |
off64_t offset;
|
|
Packit |
577717 |
long long w_depth;
|
|
Packit |
577717 |
long long direct;
|
|
Packit |
577717 |
char *buffer,*free_addr;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct cache_ent *ce;
|
|
Packit |
577717 |
long temp;
|
|
Packit |
577717 |
if(fd==0LL)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("Setting up write buffer insane\n");
|
|
Packit |
577717 |
exit(178);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(gc->w_count > w_depth)
|
|
Packit |
577717 |
async_wait_for_write(gc);
|
|
Packit |
577717 |
ce=(struct cache_ent *)malloc((size_t)sizeof(struct cache_ent));
|
|
Packit |
577717 |
if(ce == (struct cache_ent *)0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("Malloc failed 1\n");
|
|
Packit |
577717 |
exit(179);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
bzero(ce,sizeof(struct cache_ent));
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes=(int)fd;
|
|
Packit |
577717 |
ce->myaiocb.aio_offset=(off64_t)offset;
|
|
Packit |
577717 |
if(!direct)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
ce->real_address = (char *)malloc((size_t)(size+page_size));
|
|
Packit |
577717 |
temp=(long)ce->real_address;
|
|
Packit |
577717 |
temp = (temp+page_size) & ~(page_size-1);
|
|
Packit |
577717 |
ce->myaiocb.aio_buf=(volatile void *)temp;
|
|
Packit |
577717 |
}else
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
ce->myaiocb.aio_buf=(volatile void *)buffer;
|
|
Packit |
577717 |
ce->real_address=(char *)free_addr;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(ce->myaiocb.aio_buf == 0)
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ce->myaiocb64.aio_fildes=(int)fd;
|
|
Packit |
577717 |
ce->myaiocb64.aio_offset=(off64_t)offset;
|
|
Packit |
577717 |
if(!direct)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
ce->real_address = (char *)malloc((size_t)(size+page_size));
|
|
Packit |
577717 |
temp=(long)ce->real_address;
|
|
Packit |
577717 |
temp = (temp+page_size) & ~(page_size-1);
|
|
Packit |
577717 |
ce->myaiocb64.aio_buf=(volatile void *)temp;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
ce->myaiocb64.aio_buf=(volatile void *)buffer;
|
|
Packit |
577717 |
ce->real_address=(char *)free_addr;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(ce->myaiocb64.aio_buf == 0)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes=(int)fd;
|
|
Packit |
577717 |
ce->myaiocb.aio_offset=(off_t)offset;
|
|
Packit |
577717 |
if(!direct)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
ce->real_address = (char *)malloc((size_t)(size+page_size));
|
|
Packit |
577717 |
temp=(long)ce->real_address;
|
|
Packit |
577717 |
temp = (temp+page_size) & ~(page_size-1);
|
|
Packit |
577717 |
ce->myaiocb.aio_buf=(volatile void *)temp;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
ce->myaiocb.aio_buf=(volatile void *)buffer;
|
|
Packit |
577717 |
ce->real_address=(char *)free_addr;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(ce->myaiocb.aio_buf == 0)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("Malloc failed 2\n");
|
|
Packit |
577717 |
exit(180);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
ce->myaiocb.aio_reqprio=0;
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes=(size_t)size;
|
|
Packit |
577717 |
ce->myaiocb.aio_sigevent.sigev_notify=SIGEV_NONE;
|
|
Packit |
577717 |
ce->myaiocb.aio_lio_opcode=(int)op;
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ce->myaiocb64.aio_reqprio=0;
|
|
Packit |
577717 |
ce->myaiocb64.aio_nbytes=(size_t)size;
|
|
Packit |
577717 |
ce->myaiocb64.aio_sigevent.sigev_notify=SIGEV_NONE;
|
|
Packit |
577717 |
ce->myaiocb64.aio_lio_opcode=(int)op;
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ce->myaiocb.aio_reqprio=0;
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes=(size_t)size;
|
|
Packit |
577717 |
ce->myaiocb.aio_sigevent.sigev_notify=SIGEV_NONE;
|
|
Packit |
577717 |
ce->myaiocb.aio_lio_opcode=(int)op;
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
ce->fd=(int)fd;
|
|
Packit |
577717 |
return(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*************************************************************************
|
|
Packit |
577717 |
* Put it on the outbound queue.
|
|
Packit |
577717 |
*************************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
async_put_on_write_queue(gc,ce)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
struct cache_ent *ce;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
ce->forward=0;
|
|
Packit |
577717 |
ce->back=gc->w_tail;
|
|
Packit |
577717 |
if(gc->w_tail)
|
|
Packit |
577717 |
gc->w_tail->forward = ce;
|
|
Packit |
577717 |
gc->w_tail= ce;
|
|
Packit |
577717 |
if(!gc->w_head)
|
|
Packit |
577717 |
gc->w_head=ce;
|
|
Packit |
577717 |
gc->w_count++;
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*************************************************************************
|
|
Packit |
577717 |
* Cleanup all outstanding writes
|
|
Packit |
577717 |
*************************************************************************/
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
async_write_finish(gc)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
while(gc->w_head)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/*printf("async_write_finish: Waiting for buffer %x to finish\n",gc->w_head->myaiocb64.aio_buf);*/
|
|
Packit |
577717 |
async_wait_for_write(gc);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*************************************************************************
|
|
Packit |
577717 |
* Wait for an I/O to finish
|
|
Packit |
577717 |
*************************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
async_wait_for_write(gc)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct cache_ent *ce;
|
|
Packit |
577717 |
size_t ret,retval;
|
|
Packit |
577717 |
if(gc->w_head==0)
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
ce=gc->w_head;
|
|
Packit |
577717 |
gc->w_head=ce->forward;
|
|
Packit |
577717 |
gc->w_count--;
|
|
Packit |
577717 |
ce->forward=0;
|
|
Packit |
577717 |
if(ce==gc->w_tail)
|
|
Packit |
577717 |
gc->w_tail=0;
|
|
Packit |
577717 |
/*printf("Wait for buffer %x offset %lld size %d to finish\n",
|
|
Packit |
577717 |
ce->myaiocb64.aio_buf,
|
|
Packit |
577717 |
ce->myaiocb64.aio_offset,
|
|
Packit |
577717 |
ce->myaiocb64.aio_nbytes);
|
|
Packit |
577717 |
printf("write count %lld \n",gc->w_count);
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret=aio_error64(&ce->myaiocb64))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_suspend(ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("aio_error 5: ret %d %d\n",ret,errno);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
printf("fd %d offset %lld size %d\n",
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("fd %d offset %lld size %d\n",
|
|
Packit |
577717 |
ce->myaiocb64.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb64.aio_offset,
|
|
Packit |
577717 |
ce->myaiocb64.aio_nbytes);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("fd %d offset %lld size %d\n",
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
exit(181);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
retval=aio_return(&ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
#if defined(__CrayX1__)
|
|
Packit |
577717 |
retval=aio_return64((aiocb64_t *)&ce->myaiocb64);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
retval=aio_return64((struct aiocb64 *)&ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
retval=aio_return(&ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if((int)retval < 0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("aio_return error: %d\n",errno);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if(!ce->direct)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/* printf("Freeing buffer %x\n",ce->real_address);*/
|
|
Packit |
577717 |
free((void *)(ce->real_address));
|
|
Packit |
577717 |
free((void *)ce);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*************************************************************************
|
|
Packit |
577717 |
* This routine is a generic async writer assist funtion. It takes
|
|
Packit |
577717 |
* the same calling parameters as write() but also extends the
|
|
Packit |
577717 |
* interface to include:
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* offset ..... offset in the file.
|
|
Packit |
577717 |
* depth ..... How much read-ahead do you want.
|
|
Packit |
577717 |
* free_addr .. address of memory to free after write is completed.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*************************************************************************/
|
|
Packit |
577717 |
size_t
|
|
Packit |
577717 |
async_write_no_copy(gc,fd,buffer,size,offset,depth,free_addr)
|
|
Packit |
577717 |
struct cache *gc;
|
|
Packit |
577717 |
long long fd,size;
|
|
Packit |
577717 |
char *buffer;
|
|
Packit |
577717 |
off64_t offset;
|
|
Packit |
577717 |
long long depth;
|
|
Packit |
577717 |
char *free_addr;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
struct cache_ent *ce;
|
|
Packit |
577717 |
size_t ret;
|
|
Packit |
577717 |
long long direct = 1;
|
|
Packit |
577717 |
ce=allocate_write_buffer(gc,fd,offset,size,(long long)LIO_WRITE,depth,direct,buffer,free_addr);
|
|
Packit |
577717 |
ce->direct=0; /* have library de-allocate the buffer */
|
|
Packit |
577717 |
async_put_on_write_queue(gc,ce);
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
printf("awnc: fd %d offset %lld, size %d\n",ce->myaiocb64.aio_fildes,
|
|
Packit |
577717 |
ce->myaiocb64.aio_offset,
|
|
Packit |
577717 |
ce->myaiocb64.aio_nbytes);
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
again:
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
ret=aio_write(&ce->myaiocb);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ret=aio_write64(&ce->myaiocb64);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
ret=aio_write(&ce->myaiocb);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
if(ret==-1)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if(errno==EAGAIN)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
async_wait_for_write(gc);
|
|
Packit |
577717 |
goto again;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if(errno==0)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/* Compensate for bug in async library */
|
|
Packit |
577717 |
async_wait_for_write(gc);
|
|
Packit |
577717 |
goto again;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
printf("Error in aio_write: ret %d errno %d\n",ret,errno);
|
|
Packit |
577717 |
#ifdef _LARGEFILE64_SOURCE
|
|
Packit |
577717 |
#ifdef __LP64__
|
|
Packit |
577717 |
printf("aio_write_no_copy: fd %d buffer %lx offset %lld size %d\n",
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
(long)(ce->myaiocb.aio_buf),
|
|
Packit |
577717 |
ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes);
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("aio_write_no_copy: fd %d buffer %lx offset %lld size %d\n",
|
|
Packit |
577717 |
ce->myaiocb64.aio_fildes,
|
|
Packit |
577717 |
(long)(ce->myaiocb64.aio_buf),
|
|
Packit |
577717 |
ce->myaiocb64.aio_offset,
|
|
Packit |
577717 |
ce->myaiocb64.aio_nbytes);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
printf("aio_write_no_copy: fd %d buffer %lx offset %ld size %d\n",
|
|
Packit |
577717 |
ce->myaiocb.aio_fildes,
|
|
Packit |
577717 |
(long)(ce->myaiocb.aio_buf),
|
|
Packit |
577717 |
ce->myaiocb.aio_offset,
|
|
Packit |
577717 |
ce->myaiocb.aio_nbytes);
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
exit(182);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
return((ssize_t)size);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
void mbcopy(source, dest, len)
|
|
Packit |
577717 |
char *source,*dest;
|
|
Packit |
577717 |
size_t len;
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
*dest++=*source++;
|
|
Packit |
577717 |
}
|