From d0f0d2f428dc25eb795dcb6ad2886bde36551ef1 Mon Sep 17 00:00:00 2001 From: Felix Blyakher Date: Mon, 6 Apr 2009 10:18:34 -0500 Subject: [PATCH] xfstests: fix async io error handling in fsx The result of async io returned in the event.res in addition to the number of bytes read/written provides negated error number. The broken libaio defines event.res as unsigned while the same structure in the kernel defines it as signed. The kernel indeed treats it as signed, and returns the negated error number. Till libaio is fixed we provide the signed long temp var. Also set errno for each error condition in aio_rw, as the caller is not aio aware and expects ret(-1)+errno by the traditional libc convention. Signed-off-by: Felix Blyakher Reviewed-by: Christoph Hellwig --- ltp/fsx.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/ltp/fsx.c b/ltp/fsx.c index ebe53249..210afd57 100644 --- a/ltp/fsx.c +++ b/ltp/fsx.c @@ -962,6 +962,7 @@ __aio_rw(int rw, int fd, char *buf, unsigned len, unsigned offset) static struct timespec ts; struct iocb *iocbs[] = { &iocb }; int ret; + long res; if (rw == READ) { io_prep_pread(&iocb, fd, buf, len, offset); @@ -976,21 +977,49 @@ __aio_rw(int rw, int fd, char *buf, unsigned len, unsigned offset) fprintf(stderr, "errcode=%d\n", ret); fprintf(stderr, "aio_rw: io_submit failed: %s\n", strerror(ret)); - return(-1); + goto out_error; } ret = io_getevents(io_ctx, 1, 1, &event, &ts); if (ret != 1) { - fprintf(stderr, "errcode=%d\n", ret); - fprintf(stderr, "aio_rw: io_getevents failed: %s\n", - strerror(ret)); - return -1; + if (ret == 0) + fprintf(stderr, "aio_rw: no events available\n"); + else { + fprintf(stderr, "errcode=%d\n", -ret); + fprintf(stderr, "aio_rw: io_getevents failed: %s\n", + strerror(-ret)); + } + goto out_error; } if (len != event.res) { - fprintf(stderr, "bad read length: %lu instead of %u\n", - event.res, len); + /* + * The b0rked libaio defines event.res as unsigned. + * However the kernel strucuture has it signed, + * and it's used to pass negated error value. + * Till the library is fixed use the temp var. + */ + res = (long)event.res; + if (res >= 0) + fprintf(stderr, "bad io length: %lu instead of %u\n", + res, len); + else { + fprintf(stderr, "errcode=%d\n", -res); + fprintf(stderr, "aio_rw: async io failed: %s\n", + strerror(-res)); + ret = res; + goto out_error; + } + } return event.res; + +out_error: + /* + * The caller expects error return in traditional libc + * convention, i.e. -1 and the errno set to error. + */ + errno = -ret; + return -1; } int aio_rw(int rw, int fd, char *buf, unsigned len, unsigned offset) -- 2.30.2