diff options
Diffstat (limited to 'api/src/glfs-fops.c')
-rw-r--r-- | api/src/glfs-fops.c | 91 |
1 files changed, 81 insertions, 10 deletions
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index f58de45a8..3fd3cef2a 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -587,10 +587,6 @@ glfs_io_async_task (void *data) ssize_t ret = 0; switch (gio->op) { - case GF_FOP_READ: - ret = glfs_preadv (gio->glfd, gio->iov, gio->count, - gio->offset, gio->flags); - break; case GF_FOP_WRITE: ret = glfs_pwritev (gio->glfd, gio->iov, gio->count, gio->offset, gio->flags); @@ -611,23 +607,90 @@ glfs_io_async_task (void *data) int +glfs_preadv_async_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, struct iovec *iovec, + int count, struct iatt *stbuf, struct iobref *iobref, + dict_t *xdata) +{ + struct glfs_io *gio = NULL; + xlator_t *subvol = NULL; + struct glfs *fs = NULL; + struct glfs_fd *glfd = NULL; + + + gio = frame->local; + frame->local = NULL; + subvol = cookie; + glfd = gio->glfd; + fs = glfd->fs; + + if (op_ret <= 0) + goto out; + + op_ret = iov_copy (gio->iov, gio->count, iovec, count); + + glfd->offset = gio->offset + op_ret; +out: + errno = op_errno; + gio->fn (gio->glfd, op_ret, gio->data); + + GF_FREE (gio->iov); + GF_FREE (gio); + STACK_DESTROY (frame->root); + glfs_subvol_done (fs, subvol); + + return 0; +} + + +int glfs_preadv_async (struct glfs_fd *glfd, const struct iovec *iovec, int count, off_t offset, int flags, glfs_io_cbk fn, void *data) { struct glfs_io *gio = NULL; int ret = 0; + call_frame_t *frame = NULL; + xlator_t *subvol = NULL; + glfs_t *fs = NULL; + fd_t *fd = NULL; + + __glfs_entry_fd (glfd); + + subvol = glfs_active_subvol (glfd->fs); + if (!subvol) { + ret = -1; + errno = EIO; + goto out; + } + + fd = glfs_resolve_fd (glfd->fs, subvol, glfd); + if (!fd) { + ret = -1; + errno = EBADFD; + goto out; + } + + fs = glfd->fs; + + frame = syncop_create_frame (THIS); + if (!frame) { + ret = -1; + errno = ENOMEM; + goto out; + } gio = GF_CALLOC (1, sizeof (*gio), glfs_mt_glfs_io_t); if (!gio) { + ret = -1; errno = ENOMEM; - return -1; + goto out; } gio->iov = iov_dup (iovec, count); if (!gio->iov) { - GF_FREE (gio); + ret = -1; errno = ENOMEM; - return -1; + goto out; } gio->op = GF_FOP_READ; @@ -638,15 +701,23 @@ glfs_preadv_async (struct glfs_fd *glfd, const struct iovec *iovec, int count, gio->fn = fn; gio->data = data; - ret = synctask_new (glfs_from_glfd (glfd)->ctx->env, - glfs_io_async_task, glfs_io_async_cbk, - NULL, gio); + frame->local = gio; + STACK_WIND_COOKIE (frame, glfs_preadv_async_cbk, subvol, subvol, + subvol->fops->readv, fd, iov_length (iovec, count), + offset, flags, NULL); + +out: if (ret) { GF_FREE (gio->iov); GF_FREE (gio); + STACK_DESTROY (frame->root); + glfs_subvol_done (fs, subvol); } + if (fd) + fd_unref (fd); + return ret; } |