From: Chris Mason 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. Signed-off-by: Jan Kara diff -rupX /home/jack/.kerndiffexclude linux-2.6.15/fs/ext2/fsync.c linux-2.6.15-1-ext2_sync_check/fs/ext2/fsync.c --- linux-2.6.15/fs/ext2/fsync.c 2004-10-18 23:55:24.000000000 +0200 +++ linux-2.6.15-1-ext2_sync_check/fs/ext2/fsync.c 2006-01-13 22:56:43.000000000 +0100 @@ -25,6 +25,7 @@ #include "ext2.h" #include #include /* for fsync_inode_buffers() */ +#include /* @@ -35,10 +36,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))