diff options
| author | Anand Avati <avati@redhat.com> | 2013-09-11 00:49:57 -0700 | 
|---|---|---|
| committer | Anand Avati <avati@redhat.com> | 2013-09-17 11:41:42 -0700 | 
| commit | 8eb3898578a4fe359934da57c0e51cfaa21685d4 (patch) | |
| tree | ac3a141a243ea17e27addebef5ed9aa4008753f1 | |
| parent | a5b74203589f1c06d86d50fb56940571bfc13e20 (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/5897
| -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 8df237fd3..e411f5a83 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); @@ -614,23 +610,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; @@ -641,15 +704,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;  }  | 
