engine: e4defrag fix error reporting
authorDmitry Monakhov <dmonakhov@openvz.org>
Fri, 7 Apr 2017 04:56:49 +0000 (07:56 +0300)
committerDmitry Monakhov <dmonakhov@openvz.org>
Fri, 7 Apr 2017 04:56:49 +0000 (07:56 +0300)
IOC_MOVE_EXT returns 0 if the requested range is beyond i_size. In that
case we currently set io_u->resid = io_u->xfer_buflen, but
io_queue_event() interprets that as a zero read and fails with EIO. We
definitely do not want this behaviour so set io_u->error explicitly to
EINVAL so we fail with that instead when we are in this scenario.

engines/e4defrag.c

index 1e4996f155ef5d258ae98a2a6748701c84e5413c..4b444888aa9bb51c5a660aee67f385dd6f20c021 100644 (file)
@@ -172,8 +172,13 @@ static int fio_e4defrag_queue(struct thread_data *td, struct io_u *io_u)
                len = io_u->xfer_buflen;
 
        if (len != io_u->xfer_buflen) {
                len = io_u->xfer_buflen;
 
        if (len != io_u->xfer_buflen) {
-               io_u->resid = io_u->xfer_buflen - len;
-               io_u->error = 0;
+               if (len) {
+                       io_u->resid = io_u->xfer_buflen - len;
+                       io_u->error = 0;
+               } else {
+                       /* access beyond i_size */
+                       io_u->error = EINVAL;
+               }
        }
        if (ret)
                io_u->error = errno;
        }
        if (ret)
                io_u->error = errno;