vfs_aio_fork: Fix vfs_aio_pread
authorVolker Lendecke <vl@samba.org>
Fri, 8 Dec 2017 13:07:06 +0000 (14:07 +0100)
committerJeremy Allison <jra@samba.org>
Tue, 12 Dec 2017 19:37:08 +0000 (20:37 +0100)
Copy the data that the child read into the caller's buffer. This can't
have been used in half a decade at least...

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/modules/vfs_aio_fork.c

index 3eaa26774f5b0f364cd3c33d8a450607ac152b9a..1538ed9cf4641b7c8fabed34b4f6a7220c673b9a 100644 (file)
@@ -534,6 +534,8 @@ static int get_idle_child(struct vfs_handle_struct *handle,
 
 struct aio_fork_pread_state {
        struct aio_child *child;
 
 struct aio_fork_pread_state {
        struct aio_child *child;
+       size_t n;
+       void *data;
        ssize_t ret;
        struct vfs_aio_state vfs_aio_state;
 };
        ssize_t ret;
        struct vfs_aio_state vfs_aio_state;
 };
@@ -562,6 +564,8 @@ static struct tevent_req *aio_fork_pread_send(struct vfs_handle_struct *handle,
        if (req == NULL) {
                return NULL;
        }
        if (req == NULL) {
                return NULL;
        }
+       state->n = n;
+       state->data = data;
 
        if (n > 128*1024) {
                /* TODO: support variable buffers */
 
        if (n > 128*1024) {
                /* TODO: support variable buffers */
@@ -629,12 +633,20 @@ static void aio_fork_pread_done(struct tevent_req *subreq)
                return;
        }
 
                return;
        }
 
-       state->child->busy = false;
-
        retbuf = (struct rw_ret *)buf;
        state->ret = retbuf->size;
        state->vfs_aio_state.error = retbuf->ret_errno;
        state->vfs_aio_state.duration = retbuf->duration;
        retbuf = (struct rw_ret *)buf;
        state->ret = retbuf->size;
        state->vfs_aio_state.error = retbuf->ret_errno;
        state->vfs_aio_state.duration = retbuf->duration;
+
+       if ((size_t)state->ret > state->n) {
+               tevent_req_error(req, EIO);
+               state->child->busy = false;
+               return;
+       }
+       memcpy(state->data, state->child->map->ptr, state->ret);
+
+       state->child->busy = false;
+
        tevent_req_done(req);
 }
 
        tevent_req_done(req);
 }