diff options
author | Anand Avati <avati@redhat.com> | 2013-09-11 00:49:57 -0700 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-11-26 11:02:01 -0800 |
commit | 24e4b5d12be5d92a4e5c3167372f88cd3dfa720a (patch) | |
tree | 3c64bdc3d8f56189cdaa2a23b8e9e7ebd50b47f9 /api/src/glfs-fops.c | |
parent | fdf3d652acbbe6aa145b7dccd193392b9d1581bd (diff) |
gfapi: use native STACK_WIND for read _async() calls
There is little value in using synctask wrappers for async IO
requests, as STACK_WIND is asynchronous by nature already.
Skip going through synctask for read/write async calls.
Change-Id: Ifde331d7c97e0f33426da6ef4377c5ba70dddc06
BUG: 1009134
Signed-off-by: Anand Avati <avati@redhat.com>
Reviewed-on: http://review.gluster.org/6325
Tested-by: Gluster Build System <jenkins@build.gluster.com>
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 f58de45a8ae..3fd3cef2a3f 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; } |