Improve error logging and handling
authorJens Axboe <jens.axboe@oracle.com>
Mon, 5 Mar 2007 09:06:06 +0000 (10:06 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Mon, 5 Mar 2007 09:06:06 +0000 (10:06 +0100)
If we see an IO anomaly, make sure we dump as much info about the
filename, size, offset, etc.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
fio.c
fio.h
io_u.c

diff --git a/fio.c b/fio.c
index 22f0124459352e2011a0fe99ced7fb65e514b5f7..b668d856e9d3e9fd49c0ffc807ece26625f61d13 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -270,6 +270,8 @@ static void do_verify(struct thread_data *td)
 
        io_u = NULL;
        while (!td->terminate) {
+               int ret2;
+
                io_u = __get_io_u(td);
                if (!io_u)
                        break;
@@ -297,7 +299,7 @@ requeue:
                case FIO_Q_COMPLETED:
                        if (io_u->error)
                                ret = -io_u->error;
-                       if (io_u->xfer_buflen != io_u->resid && io_u->resid) {
+                       else if (io_u->xfer_buflen != io_u->resid && io_u->resid) {
                                int bytes = io_u->xfer_buflen - io_u->resid;
 
                                io_u->xfer_buflen = io_u->resid;
@@ -312,7 +314,9 @@ requeue:
                        break;
                case FIO_Q_BUSY:
                        requeue_io_u(td, &io_u);
-                       ret = td_io_commit(td);
+                       ret2 = td_io_commit(td);
+                       if (ret2 < 0)
+                               ret = ret2;
                        break;
                default:
                        assert(ret < 0);
@@ -396,6 +400,7 @@ static void do_io(struct thread_data *td)
                long bytes_done = 0;
                int min_evts = 0;
                struct io_u *io_u;
+               int ret2;
 
                if (td->terminate)
                        break;
@@ -415,11 +420,9 @@ requeue:
 
                switch (ret) {
                case FIO_Q_COMPLETED:
-                       if (io_u->error) {
-                               ret = io_u->error;
-                               break;
-                       }
-                       if (io_u->xfer_buflen != io_u->resid && io_u->resid) {
+                       if (io_u->error)
+                               ret = -io_u->error;
+                       else if (io_u->xfer_buflen != io_u->resid && io_u->resid) {
                                int bytes = io_u->xfer_buflen - io_u->resid;
 
                                io_u->xfer_buflen = io_u->resid;
@@ -442,7 +445,9 @@ requeue:
                        break;
                case FIO_Q_BUSY:
                        requeue_io_u(td, &io_u);
-                       ret = td_io_commit(td);
+                       ret2 = td_io_commit(td);
+                       if (ret2 < 0)
+                               ret = ret2;
                        break;
                default:
                        assert(ret < 0);
diff --git a/fio.h b/fio.h
index 9b8bed76172f8d9ccdcb29793929997370c3b095..daf316b4fb917a41f11ff91f72366d2a8c4f7ff1 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -672,6 +672,7 @@ extern void requeue_io_u(struct thread_data *, struct io_u **);
 extern long __must_check io_u_sync_complete(struct thread_data *, struct io_u *);
 extern long __must_check io_u_queued_complete(struct thread_data *, int);
 extern void io_u_queued(struct thread_data *, struct io_u *);
+extern void io_u_log_error(struct thread_data *, struct io_u *);
 extern void io_u_init_timeout(void);
 extern void io_u_set_timeout(struct thread_data *);
 
diff --git a/io_u.c b/io_u.c
index fa6302e6934ba502b30a68afbba2489ea137ca50..698952c7eb964bccb1c01feb2af1357108b8c0b8 100644 (file)
--- a/io_u.c
+++ b/io_u.c
@@ -486,6 +486,23 @@ out:
        return io_u;
 }
 
+void io_u_log_error(struct thread_data *td, struct io_u *io_u)
+{
+       const char *msg[] = { "read", "write", "sync" };
+
+       log_err("fio: io_u error");
+
+       if (io_u->file)
+               log_err(" on file %s", io_u->file->file_name);
+
+       log_err(": %s\n", strerror(io_u->error));
+
+       log_err("     %s offset=%llu, buflen=%lu\n", msg[io_u->ddir], io_u->offset, io_u->xfer_buflen);
+
+       if (!td->error)
+               td_verror(td, io_u->error, "io_u error");
+}
+
 static void io_completed(struct thread_data *td, struct io_u *io_u,
                         struct io_completion_data *icd)
 {
@@ -529,8 +546,10 @@ static void io_completed(struct thread_data *td, struct io_u *io_u,
                        if (ret && !icd->error)
                                icd->error = ret;
                }
-       } else
+       } else {
                icd->error = io_u->error;
+               io_u_log_error(td, io_u);
+       }
 }
 
 static void init_icd(struct io_completion_data *icd, int nr)