sync_filesystem is called from several kernel subsystems to write out a superblock. After writing out the inodes, it calls the superblock sync_fs operation, which is an int return operation. That error code is then discarded. It then calls __sync_blockdev and returns an error if that fails. Most filesystems that have a sync_fs operation do most of the work inside that operation and then return an error if it fails. With those filesystems, the sync_blockdev is effectively a no-op and may very well not return an error even though writeback failed. Have __sync_filesystem preserve the error from sync_fs and return that if it fails, or the return from __sync_blockdev if it succeeds. Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx> --- fs/sync.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/sync.c b/fs/sync.c index 45ecf6854595..ec93aac4feb9 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -29,14 +29,18 @@ */ static int __sync_filesystem(struct super_block *sb, int wait) { + int fs_ret = 0, bd_ret; + if (wait) sync_inodes_sb(sb); else writeback_inodes_sb(sb, WB_REASON_SYNC); if (sb->s_op->sync_fs) - sb->s_op->sync_fs(sb, wait); - return __sync_blockdev(sb->s_bdev, wait); + fs_ret = sb->s_op->sync_fs(sb, wait); + bd_ret = __sync_blockdev(sb->s_bdev, wait); + + return fs_ret ? fs_ret : bd_ret; } /* -- 2.9.4