summaryrefslogtreecommitdiffstats
path: root/xlators/storage/posix/src/posix-aio.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/storage/posix/src/posix-aio.c')
-rw-r--r--xlators/storage/posix/src/posix-aio.c66
1 files changed, 60 insertions, 6 deletions
diff --git a/xlators/storage/posix/src/posix-aio.c b/xlators/storage/posix/src/posix-aio.c
index ac0ce870506..075fd320e7e 100644
--- a/xlators/storage/posix/src/posix-aio.c
+++ b/xlators/storage/posix/src/posix-aio.c
@@ -31,6 +31,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;
@@ -49,7 +90,6 @@ posix_aio_readv_complete (struct posix_aio_cb *paiocb, int res, int res2)
call_frame_t *frame = NULL;
xlator_t *this = NULL;
struct iobuf *iobuf = NULL;
- struct iatt prebuf = {0,};
struct iatt postbuf = {0,};
int _fd = -1;
int op_ret = -1;
@@ -65,7 +105,6 @@ posix_aio_readv_complete (struct posix_aio_cb *paiocb, int res, int res2)
this = frame->this;
priv = this->private;
iobuf = paiocb->iobuf;
- prebuf = paiocb->prebuf;
_fd = paiocb->fd;
offset = paiocb->offset;
@@ -154,7 +193,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,
@@ -198,7 +237,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);
@@ -304,7 +350,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,
@@ -346,7 +392,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);