diff options
Diffstat (limited to 'xlators/storage/posix/src/posix-aio.c')
| -rw-r--r-- | xlators/storage/posix/src/posix-aio.c | 114 |
1 files changed, 83 insertions, 31 deletions
diff --git a/xlators/storage/posix/src/posix-aio.c b/xlators/storage/posix/src/posix-aio.c index a673c2c15..c3bbddd67 100644 --- a/xlators/storage/posix/src/posix-aio.c +++ b/xlators/storage/posix/src/posix-aio.c @@ -1,22 +1,12 @@ /* - Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ + Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" @@ -31,6 +21,47 @@ #include <libaio.h> +void +__posix_fd_set_odirect (fd_t *fd, struct posix_fd *pfd, int opflags, + off_t offset, size_t size) +{ + int odirect = 0; + int flags = 0; + int ret = 0; + + odirect = pfd->odirect; + + if ((fd->flags|opflags) & O_DIRECT) { + /* if instructed, use O_DIRECT always */ + odirect = 1; + } else { + /* else use O_DIRECT when feasible */ + if ((offset|size) & 0xfff) + odirect = 0; + else + odirect = 1; + } + + if (!odirect && pfd->odirect) { + flags = fcntl (pfd->fd, F_GETFL); + ret = fcntl (pfd->fd, F_SETFL, (flags & (~O_DIRECT))); + pfd->odirect = 0; + } + + if (odirect && !pfd->odirect) { + flags = fcntl (pfd->fd, F_GETFL); + ret = fcntl (pfd->fd, F_SETFL, (flags | O_DIRECT)); + pfd->odirect = 1; + } + + if (ret) { + gf_log (THIS->name, GF_LOG_WARNING, + "fcntl() failed (%s). fd=%d flags=%d pfd->odirect=%d", + strerror (errno), pfd->fd, flags, pfd->odirect); + } +} + + struct posix_aio_cb { struct iocb iocb; call_frame_t *frame; @@ -105,11 +136,7 @@ posix_aio_readv_complete (struct posix_aio_cb *paiocb, int res, int res2) /* Hack to notify higher layers of EOF. */ - if (postbuf.ia_size == 0) - op_errno = ENOENT; - else if ((offset + iov.iov_len) == postbuf.ia_size) - op_errno = ENOENT; - else if (offset > postbuf.ia_size) + if (!postbuf.ia_size || (offset + iov.iov_len) >= postbuf.ia_size) op_errno = ENOENT; LOCK (&priv->lock); @@ -152,7 +179,7 @@ posix_aio_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, priv = this->private; - ret = posix_fd_ctx_get_off (fd, this, &pfd, offset); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { op_errno = -ret; gf_log (this->name, GF_LOG_WARNING, @@ -196,7 +223,14 @@ posix_aio_readv (call_frame_t *frame, xlator_t *this, fd_t *fd, iocb = &paiocb->iocb; - ret = io_submit (priv->ctxp, 1, &iocb); + LOCK (&fd->lock); + { + __posix_fd_set_odirect (fd, pfd, flags, offset, size); + + ret = io_submit (priv->ctxp, 1, &iocb); + } + UNLOCK (&fd->lock); + if (ret != 1) { gf_log (this->name, GF_LOG_ERROR, "io_submit() returned %d", ret); @@ -302,7 +336,7 @@ posix_aio_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, priv = this->private; - ret = posix_fd_ctx_get_off (fd, this, &pfd, offset); + ret = posix_fd_ctx_get (fd, this, &pfd); if (ret < 0) { op_errno = -ret; gf_log (this->name, GF_LOG_WARNING, @@ -344,7 +378,15 @@ posix_aio_writev (call_frame_t *frame, xlator_t *this, fd_t *fd, } - ret = io_submit (priv->ctxp, 1, &iocb); + LOCK (&fd->lock); + { + __posix_fd_set_odirect (fd, pfd, flags, offset, + iov_length (iov, count)); + + ret = io_submit (priv->ctxp, 1, &iocb); + } + UNLOCK (&fd->lock); + if (ret != 1) { gf_log (this->name, GF_LOG_ERROR, "io_submit() returned %d", ret); @@ -431,7 +473,7 @@ posix_aio_init (xlator_t *this) ret = io_setup (POSIX_AIO_MAX_NR_EVENTS, &priv->ctxp); if ((ret == -1 && errno == ENOSYS) || ret == -ENOSYS) { gf_log (this->name, GF_LOG_WARNING, - "Linux AIO not availble at run-time." + "Linux AIO not available at run-time." " Continuing with synchronous IO"); ret = 0; goto out; @@ -444,8 +486,8 @@ posix_aio_init (xlator_t *this) goto out; } - ret = pthread_create (&priv->aiothread, NULL, - posix_aio_thread, this); + ret = gf_thread_create (&priv->aiothread, NULL, + posix_aio_thread, this); if (ret != 0) { io_destroy (priv->ctxp); goto out; @@ -500,7 +542,7 @@ int posix_aio_on (xlator_t *this) { gf_log (this->name, GF_LOG_INFO, - "Linux AIO not availble at build-time." + "Linux AIO not available at build-time." " Continuing with synchronous IO"); return 0; } @@ -509,9 +551,19 @@ int posix_aio_off (xlator_t *this) { gf_log (this->name, GF_LOG_INFO, - "Linux AIO not availble at build-time." + "Linux AIO not available at build-time." " Continuing with synchronous IO"); return 0; } +void +__posix_fd_set_odirect (fd_t *fd, struct posix_fd *pfd, int opflags, + off_t offset, size_t size) +{ + xlator_t *this = THIS; + gf_log (this->name, GF_LOG_INFO, + "Linux AIO not available at build-time." + " Continuing with synchronous IO"); + return; +} #endif |
