+++ /dev/null
-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
-@@ -2497,7 +2497,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
-@@ -2515,10 +2515,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);