aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2008-09-12 13:50:12 +0000
committerIgor Sysoev <igor@sysoev.ru>2008-09-12 13:50:12 +0000
commitfae2c00d02d3631347a17deab2709968be1a05c7 (patch)
treea62d5986fc44f517e87de51567145b12bbaab078 /src
parent0f8ea4de461b5fc54b69e09364c94b066363c0c9 (diff)
downloadnginx-fae2c00d02d3631347a17deab2709968be1a05c7.tar.gz
nginx-fae2c00d02d3631347a17deab2709968be1a05c7.zip
disable directio for unaligned reads in Linux
Diffstat (limited to 'src')
-rw-r--r--src/core/ngx_buf.h3
-rw-r--r--src/core/ngx_output_chain.c37
-rw-r--r--src/os/unix/ngx_files.c17
-rw-r--r--src/os/unix/ngx_files.h19
-rw-r--r--src/os/win32/ngx_files.c8
-rw-r--r--src/os/win32/ngx_files.h7
6 files changed, 79 insertions, 12 deletions
diff --git a/src/core/ngx_buf.h b/src/core/ngx_buf.h
index d16656d6b..ce26c630e 100644
--- a/src/core/ngx_buf.h
+++ b/src/core/ngx_buf.h
@@ -79,6 +79,9 @@ typedef struct {
unsigned sendfile;
unsigned directio;
+#if (NGX_HAVE_ALIGNED_DIRECTIO)
+ unsigned unaligned;
+#endif
unsigned need_in_memory;
unsigned need_in_temp;
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index ecb0f31bf..391852ffe 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -355,6 +355,10 @@ ngx_output_chain_align_file_buf(ngx_output_chain_ctx_t *ctx, off_t bsize)
* to reuse the buf via ctx->free list
*/
+#if (NGX_HAVE_ALIGNED_DIRECTIO)
+ ctx->unaligned = 1;
+#endif
+
return NGX_OK;
}
@@ -491,8 +495,41 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
}
} else {
+
+#if (NGX_HAVE_ALIGNED_DIRECTIO)
+
+ if (ctx->unaligned) {
+ if (ngx_directio_off(src->file->fd) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
+ ngx_directio_off_n " \"%s\" failed",
+ src->file->name.data);
+ }
+ }
+
+#endif
+
n = ngx_read_file(src->file, dst->pos, (size_t) size, src->file_pos);
+#if (NGX_HAVE_ALIGNED_DIRECTIO)
+
+ if (ctx->unaligned) {
+ ngx_err_t err;
+
+ err = ngx_errno;
+
+ if (ngx_directio_on(src->file->fd) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, ngx_errno,
+ ngx_directio_on_n " \"%s\" failed",
+ src->file->name.data);
+ }
+
+ ngx_set_errno(err);
+
+ ctx->unaligned = 0;
+ }
+
+#endif
+
if (n == NGX_ERROR) {
return (ngx_int_t) n;
}
diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c
index ab861467e..661ecaa4e 100644
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -389,7 +389,7 @@ ngx_unlock_fd(ngx_fd_t fd)
#if (NGX_HAVE_O_DIRECT)
ngx_int_t
-ngx_directio(ngx_fd_t fd)
+ngx_directio_on(ngx_fd_t fd)
{
int flags;
@@ -402,4 +402,19 @@ ngx_directio(ngx_fd_t fd)
return fcntl(fd, F_SETFL, flags | O_DIRECT);
}
+
+ngx_int_t
+ngx_directio_off(ngx_fd_t fd)
+{
+ int flags;
+
+ flags = fcntl(fd, F_GETFL);
+
+ if (flags == -1) {
+ return -1;
+ }
+
+ return fcntl(fd, F_SETFL, flags & ~O_DIRECT);
+}
+
#endif
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 9988bcc30..d7a38d95a 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -222,23 +222,26 @@ ngx_err_t ngx_unlock_fd(ngx_fd_t fd);
#if (NGX_HAVE_O_DIRECT)
-ngx_int_t ngx_directio(ngx_fd_t fd);
-#define ngx_directio_n "fcntl(O_DIRECT)"
+ngx_int_t ngx_directio_on(ngx_fd_t fd);
+#define ngx_directio_on_n "fcntl(O_DIRECT)"
+
+ngx_int_t ngx_directio_off(ngx_fd_t fd);
+#define ngx_directio_off_n "fcntl(!O_DIRECT)"
#elif (NGX_HAVE_F_NOCACHE)
-#define ngx_directio(fd) fcntl(fd, F_NOCACHE, 1)
-#define ngx_directio_n "fcntl(F_NOCACHE)"
+#define ngx_directio_on(fd) fcntl(fd, F_NOCACHE, 1)
+#define ngx_directio_on_n "fcntl(F_NOCACHE, 1)"
#elif (NGX_HAVE_DIRECTIO)
-#define ngx_directio(fd) directio(fd, DIRECTIO_ON)
-#define ngx_directio_n "directio(DIRECTIO_ON)"
+#define ngx_directio_on(fd) directio(fd, DIRECTIO_ON)
+#define ngx_directio_on_n "directio(DIRECTIO_ON)"
#else
-#define ngx_directio(fd) 0
-#define ngx_directio_n "ngx_directio_n"
+#define ngx_directio_on(fd) 0
+#define ngx_directio_on_n "ngx_directio_on_n"
#endif
diff --git a/src/os/win32/ngx_files.c b/src/os/win32/ngx_files.c
index 20b528668..cbba0bbfb 100644
--- a/src/os/win32/ngx_files.c
+++ b/src/os/win32/ngx_files.c
@@ -505,7 +505,13 @@ ngx_file_append_mode(ngx_fd_t fd)
ngx_int_t
-ngx_directio(ngx_fd_t fd)
+ngx_directio_on(ngx_fd_t fd)
+{
+ return 0;
+}
+
+ngx_int_t
+ngx_directio_off(ngx_fd_t fd)
{
return 0;
}
diff --git a/src/os/win32/ngx_files.h b/src/os/win32/ngx_files.h
index 9f4f68199..95ea65b67 100644
--- a/src/os/win32/ngx_files.h
+++ b/src/os/win32/ngx_files.h
@@ -232,8 +232,11 @@ ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce,
off_t offset, ngx_pool_t *pool);
-ngx_int_t ngx_directio(ngx_fd_t fd);
-#define ngx_directio_n "ngx_directio_n"
+ngx_int_t ngx_directio_on(ngx_fd_t fd);
+#define ngx_directio_on_n "ngx_directio_on_n"
+
+ngx_int_t ngx_directio_off(ngx_fd_t fd);
+#define ngx_directio_off_n "ngx_directio_off_n"
#endif /* _NGX_FILES_H_INCLUDED_ */