<snipped>
> +
> + /* aio_return gets the return value of the individual op */
> + ret = aio_return(&aiocb_p[i]);
> +
> + if(op_p->u.b_rw_list.sigev.sigev_notify == SIGEV_NONE)
> + {
> + /* aio_return doesn't seem to return bytes read/written if
> + * sigev_notify == SIGEV_NONE, so we set the out size
> + * from what's requested. For reads we just leave as zero,
> + * which ends up being OK,
> + * since the amount read (if past EOF its less than requested)
> + * is determined from the bstream size.
> + */
> + if (op_p->type == BSTREAM_WRITE_LIST ||
> + op_p->type == BSTREAM_WRITE_AT)
> + {
> + *(op_p->u.b_rw_list.out_size_p) += aiocb_p[i].aio_nbytes;
> + }
> + }
> + else
> + {
> + *(op_p->u.b_rw_list.out_size_p) += ret;
> + }
> +
Nice cleanup, Sam!
Quick question regarding the comment on aio_return() and SIGEV_NONE.
Are you sure that comment/implementation is correct?
Isnt this a problem for writes() if the disk/fs is full by returning
optimistically?
Perhaps aiocb_p[i] was not memset() with 0's prior to lio_listio. See
attached program which demonstrates errors if the memset() was not done.
(Run the program with and without the memset at the top of the program and
you will see interesting errors even though there are none!)
Thanks,
Murali
#include <aio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#define BSIZE 65536
#define NUM_AIO_SUBMITTED 32
int main(void)
{
int fd, i, ret, flag = 0, status[NUM_AIO_SUBMITTED] = {0,};
struct aiocb aiocb[NUM_AIO_SUBMITTED];
struct aiocb *aiocb_array[NUM_AIO_SUBMITTED] = {NULL};
void *buffer = NULL, *buf = NULL;
struct sigevent ev;
signal(SIGHUP, SIG_IGN);
fd = open("/tmp/a.txt", O_CREAT | O_RDWR, 0700);
buffer = (void *) malloc(BSIZE * NUM_AIO_SUBMITTED);
buf = buffer;
memset(aiocb, 0, NUM_AIO_SUBMITTED * sizeof(struct aiocb));
for (i = 0; i < NUM_AIO_SUBMITTED; i++)
{
aiocb[i].aio_fildes = fd;
aiocb[i].aio_lio_opcode = LIO_WRITE;
aiocb[i].aio_reqprio = 0;
aiocb[i].aio_buf = ((char *) buf + BSIZE * i);
aiocb[i].aio_nbytes = BSIZE;
aiocb[i].aio_offset = i * BSIZE;
aiocb_array[i] = &aiocb[i];
status[i] = EINPROGRESS;
}
ev.sigev_notify = SIGEV_NONE;
ret = lio_listio(LIO_NOWAIT, aiocb_array, NUM_AIO_SUBMITTED, &ev);
if (ret != 0)
{
printf("lio_listio failed with ret %d: %s\n", ret, strerror(errno));
close(fd);
exit(1);
}
ret = 0;
flag = -1;
while (flag)
{
int ret1;
flag = -1;
for (i = 0; i < NUM_AIO_SUBMITTED; i++)
{
if (status[i] == EINPROGRESS)
{
ret1 = aio_error(&aiocb[i]);
if (ret1 != 0)
{
/* if op in progress, we have to skip it */
if (ret1 == EINPROGRESS)
{
/* we have not completed */
flag = 1;
continue;
}
else
{
printf("I/O on %d failed: %d\n", i, ret1);
status[i] = -1;
}
}
else
{
/* we have completed */
ret += aio_return(&aiocb[i]);
status[i] = 0;
if (flag < 0)
{
flag = 0;
}
}
}
}
}
printf("Wrote %d bytes\n", ret);
close(fd);
return 0;
}
_______________________________________________
Pvfs2-developers mailing list
[email protected]
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-developers