You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qubes-linux-kernel/patches.suse/osync-error

50 lines
1.5 KiB

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
@@ -2325,7 +2325,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
@@ -2343,10 +2343,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);