]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.suse/ext2-fsync-err
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.suse / ext2-fsync-err
diff --git a/src/patches/suse-2.6.27.31/patches.suse/ext2-fsync-err b/src/patches/suse-2.6.27.31/patches.suse/ext2-fsync-err
new file mode 100644 (file)
index 0000000..1e2028e
--- /dev/null
@@ -0,0 +1,52 @@
+From: Chris Mason <mason@suse.com>
+Subject: ext2 should force the FS readonly for metadata write errors
+References: 65718
+
+During fsync we should check for write errors to the block device in order to make
+sure all metadata writes have been properly written to the disk.  Without this check
+writes that happen through the normal async mechanisms might hit errors without
+reporting them back to the application.
+
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+
+---
+ fs/ext2/fsync.c |   17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/fs/ext2/fsync.c
++++ b/fs/ext2/fsync.c
+@@ -24,6 +24,7 @@
+ #include "ext2.h"
+ #include <linux/buffer_head.h>                /* for sync_mapping_buffers() */
++#include <linux/pagemap.h>
+ /*
+@@ -34,10 +35,26 @@
+ int ext2_sync_file(struct file *file, struct dentry *dentry, int datasync)
+ {
+       struct inode *inode = dentry->d_inode;
++      struct super_block *sb = inode->i_sb;
+       int err;
+       int ret;
+       ret = sync_mapping_buffers(inode->i_mapping);
++
++      /* it might make more sense to ext2_error on -EIO from
++       * sync_mapping_buffers as well, but those errors are isolated to just
++       * this file. We can safely return -EIO to fsync and let the app know
++       * they have a problem.
++       *
++       * AS_EIO indicates a failure to write a metadata page, but we have no
++       * way of knowing which one.  It's best to force readonly and let fsck
++       * figure it all out.
++       */
++      if (test_and_clear_bit(AS_EIO, &sb->s_bdev->bd_inode->i_mapping->flags)) {
++              ext2_error(sb, "ext2_sync_file", "metadata io error");
++              if (!ret)
++                      ret = -EIO;
++      }
+       if (!(inode->i_state & I_DIRTY))
+               return ret;
+       if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))