I/O errors could go unnoticed when syncing, for example the following code could write a file bigger than 10Mib on a 10Mib filesystem. With this patch, msync() will report the error originally encountered by sync(). Tuning the number of sync may be needed to reproduce the bug. make_file.c: #include #include #include #include #include #define NR_SYNC 3 /* Adjust me if needed */ #define SIZE ((10 << 20) + (100 << 10)) int main(void) { int i, fd; char *mapping; fd = open("mnt/file", O_RDWR | O_CREAT, 0600); if (fd < 0) { perror("open"); return 1; } if (ftruncate(fd, SIZE) < 0) { perror("ftruncate"); return 1; } mapping = mmap(NULL, SIZE, PROT_WRITE, MAP_SHARED, fd, 0); if (mapping == MAP_FAILED) { perror("mmap"); return 1; } memset(mapping, 0xFF, SIZE); for (i = 0; i < NR_SYNC; i++) sync(); if (msync(mapping, SIZE, MS_SYNC) < 0) { perror("msync"); return 1; } if (close(fd) < 0) { perror("close"); return 1; } puts("File written successfully => bad!\n"); return 0; } #!/bin/sh dd if=/dev/zero of=fs.10M bs=10M count=0 seek=1 mkfs.ext2 -qF fs.10M mkdir mnt mount fs.10M mnt -o loop ./make_file Signed-off-by: Guillaume Chazarain --- fs-writeback.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff -r ecb3a0d111ec fs/fs-writeback.c --- a/fs/fs-writeback.c Fri Feb 09 15:31:50 2007 +0100 +++ b/fs/fs-writeback.c Fri Feb 09 23:10:47 2007 +0100 @@ -327,6 +327,7 @@ sync_sb_inodes(struct super_block *sb, s struct address_space *mapping = inode->i_mapping; struct backing_dev_info *bdi = mapping->backing_dev_info; long pages_skipped; + int ret; if (!bdi_cap_writeback_dirty(bdi)) { list_move(&inode->i_list, &sb->s_dirty); @@ -376,7 +377,8 @@ sync_sb_inodes(struct super_block *sb, s BUG_ON(inode->i_state & I_FREEING); __iget(inode); pages_skipped = wbc->pages_skipped; - __writeback_single_inode(inode, wbc); + ret = __writeback_single_inode(inode, wbc); + mapping_set_error(mapping, ret); if (wbc->sync_mode == WB_SYNC_HOLD) { inode->dirtied_when = jiffies; list_move(&inode->i_list, &sb->s_dirty);