linux directio

Igor Sysoev is at rambler-co.ru
Thu Sep 11 19:59:46 MSD 2008


Прилагаемый патч должен решить проблемы невыравенных чтений
при использовании directio в Линуксе.


-- 
Игорь Сысоев
http://sysoev.ru
-------------- next part --------------
Index: src/core/ngx_output_chain.c
===================================================================
--- src/core/ngx_output_chain.c	(revision 1564)
+++ src/core/ngx_output_chain.c	(working copy)
@@ -355,6 +355,10 @@
      * to reuse the buf via ctx->free list
      */
 
+#if (NGX_HAVE_ALIGNED_DIRECTIO)
+    ctx->unaligned = 1;
+#endif
+
     return NGX_OK;
 }
 
@@ -491,8 +495,41 @@
         }
 
     } 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;
         }
@@ -505,8 +542,8 @@
 
         if (n != size) {
             ngx_log_error(NGX_LOG_ALERT, ctx->pool->log, 0,
-                          ngx_read_file_n " read only %z of %O from file",
-                          n, size);
+                          ngx_read_file_n " read only %z of %O from \"%s\"",
+                          n, size, src->file->name.data);
             if (n == 0) {
                 return NGX_ERROR;
             }
Index: src/core/ngx_open_file_cache.c
===================================================================
--- src/core/ngx_open_file_cache.c	(revision 1565)
+++ src/core/ngx_open_file_cache.c	(working copy)
@@ -205,6 +205,7 @@
                 of->is_file = file->is_file;
                 of->is_link = file->is_link;
                 of->is_exec = file->is_exec;
+                of->is_directio = file->is_directio;
 
                 if (!file->is_dir) {
                     file->count++;
@@ -360,6 +361,7 @@
         file->is_file = of->is_file;
         file->is_link = of->is_link;
         file->is_exec = of->is_exec;
+        file->is_directio = of->is_directio;
 
         if (!of->is_dir) {
             file->count++;
@@ -499,9 +501,9 @@
         of->fd = fd;
 
         if (of->directio <= ngx_file_size(&fi)) {
-            if (ngx_directio(fd) == -1) {
+            if (ngx_directio_on(fd) == -1) {
                 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
-                              ngx_directio_n " \"%s\" failed", name);
+                              ngx_directio_on_n " \"%s\" failed", name);
 
             } else {
                 of->is_directio = 1;
Index: src/core/ngx_open_file_cache.h
===================================================================
--- src/core/ngx_open_file_cache.h	(revision 1565)
+++ src/core/ngx_open_file_cache.h	(working copy)
@@ -63,6 +63,7 @@
     unsigned                 is_file:1;
     unsigned                 is_link:1;
     unsigned                 is_exec:1;
+    unsigned                 is_directio:1;
 
     ngx_event_t             *event;
 };
Index: src/core/ngx_buf.h
===================================================================
--- src/core/ngx_buf.h	(revision 1565)
+++ src/core/ngx_buf.h	(working copy)
@@ -79,6 +79,9 @@
 
     unsigned                     sendfile;
     unsigned                     directio;
+#if (NGX_HAVE_ALIGNED_DIRECTIO)
+    unsigned                     unaligned;
+#endif
     unsigned                     need_in_memory;
     unsigned                     need_in_temp;
 
Index: src/os/unix/ngx_files.c
===================================================================
--- src/os/unix/ngx_files.c	(revision 1565)
+++ src/os/unix/ngx_files.c	(working copy)
@@ -389,7 +389,7 @@
 #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 @@
     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: src/os/unix/ngx_files.h
===================================================================
--- src/os/unix/ngx_files.h	(revision 1565)
+++ src/os/unix/ngx_files.h	(working copy)
@@ -222,23 +222,26 @@
 
 #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: auto/os/features
===================================================================
--- auto/os/features	(revision 1565)
+++ auto/os/features	(working copy)
@@ -182,6 +182,10 @@
 . 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


More information about the nginx-ru mailing list