]> git.kaiwu.me - nginx.git/commitdiff
disable directio for unaligned reads in Linux
authorIgor Sysoev <igor@sysoev.ru>
Fri, 12 Sep 2008 13:50:12 +0000 (13:50 +0000)
committerIgor Sysoev <igor@sysoev.ru>
Fri, 12 Sep 2008 13:50:12 +0000 (13:50 +0000)
auto/os/features
src/core/ngx_buf.h
src/core/ngx_output_chain.c
src/os/unix/ngx_files.c
src/os/unix/ngx_files.h
src/os/win32/ngx_files.c
src/os/win32/ngx_files.h

index 8efed75a225838216d830f2f5c796b817e153c6d..5fcbf7f6b020641fca706d65358594ebf03237e2 100644 (file)
@@ -182,6 +182,10 @@ ngx_feature_test="fcntl(0, F_SETFL, O_DIRECT);"
 . auto/feature
 
 
+if [ $ngx_found = yes -a "$NGX_SYSTEM" = "Linux" ]; then
+    have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have
+fi
+
 ngx_feature="F_NOCACHE"
 ngx_feature_name="NGX_HAVE_F_NOCACHE"
 ngx_feature_run=no
index d16656d6b5a7d1f5822d99651496577811aabe93..ce26c630e17f9a3ee2fe4c0e2aff146e21623b56 100644 (file)
@@ -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;
 
index ecb0f31bfcb3ae811e36cdd7742b462e59708af8..391852ffe65b0d7b20788b5a08f3c08aa24707ed 100644 (file)
@@ -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;
         }
index ab861467edf59e8021d87a0cb2d4b6ddac05aa87..661ecaa4e09c2186d4c23298d629c0d1ca391c42 100644 (file)
@@ -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
index 9988bcc303befcda66242a2aec3ba60e0adf5759..d7a38d95a5fa7f78789a98f37c676e71c95fae89 100644 (file)
@@ -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
 
index 20b528668d817a3b0e32c57737808feb19f01dea..cbba0bbfb520b401fa2d59cdf96f0c65eacb1a27 100644 (file)
@@ -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;
 }
index 9f4f681995f52288e1c3fdd23be620d99294623c..95ea65b67d3a619dd54b9f04ddb6a63daae33807 100644 (file)
@@ -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_ */