]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.suse/osync-error
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / osync-error
diff --git a/src/patches/suse-2.6.27.31/patches.suse/osync-error b/src/patches/suse-2.6.27.31/patches.suse/osync-error
new file mode 100644 (file)
index 0000000..3503649
--- /dev/null
@@ -0,0 +1,49 @@
+From: mason@suse.de
+Subject: make sure O_SYNC writes properly return -EIO
+References: bnc#58622
+
+Make sure to honor the error status of synchronous writeback during
+O_SYNC writes
+
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+---
+ mm/filemap.c |   17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -2498,7 +2498,7 @@ generic_file_buffered_write(struct kiocb
+       if (likely(status >= 0)) {
+               written += status;
+-              *ppos = pos + status;
++              pos += status;
+               /*
+                * For now, when the user asks for O_SYNC, we'll actually give
+@@ -2516,10 +2516,23 @@ generic_file_buffered_write(struct kiocb
+        * to buffered writes (block instantiation inside i_size).  So we sync
+        * the file data here, to try to honour O_DIRECT expectations.
+        */
+-      if (unlikely(file->f_flags & O_DIRECT) && written)
++      if (unlikely(file->f_flags & O_DIRECT) && status >= 0 && written)
+               status = filemap_write_and_wait_range(mapping,
+                                       pos, pos + written - 1);
++      /*
++       * We must let know userspace if something hasn't been written
++       * correctly. If we got an I/O error it means we got an hardware
++       * failure, anything can be happening to the on-disk data,
++       * letting know userspace that a bit of data might have been
++       * written correctly on disk is a very low priority, compared
++       * to letting know userspace that some data has _not_ been
++       * written at all.
++       */
++      if (unlikely(status == -EIO))
++              return status;
++      *ppos = pos;
++
+       return written ? written : status;
+ }
+ EXPORT_SYMBOL(generic_file_buffered_write);