linux-hardened/fs
Neil Brown 28ae094c62 ext3 can fail badly when device stops accepting BIO_RW_BARRIER requests
Some devices - notably dm and md - can change their behaviour in response
to BIO_RW_BARRIER requests.  They might start out accepting such requests
but on reconfiguration, they find out that they cannot any more.

ext3 (and other filesystems) deal with this by always testing if
BIO_RW_BARRIER requests fail with EOPNOTSUPP, and retrying the write
requests without the barrier (probably after waiting for any pending writes
to complete).

However there is a bug in the handling for this for ext3.

When ext3 (jbd actually) decides to submit a BIO_RW_BARRIER request, it
sets the buffer_ordered flag on the buffer head.  If the request completes
successfully, the flag STAYS SET.

Other code might then write the same buffer_head after the device has been
reconfigured to not accept barriers.  This write will then fail, but the
"other code" is not ready to handle EOPNOTSUPP errors and the error will be
treated as fatal.

This can be seen without having to reconfigure a device at exactly the
wrong time by putting:

		if (buffer_ordered(bh))
			printk("OH DEAR, and ordered buffer\n");

in the while loop in "commit phase 5" of journal_commit_transaction.

If it ever prints the "OH DEAR ..." message (as it does sometimes for
me), then that request could (in different circumstances) have failed
with EOPNOTSUPP, but that isn't tested for.

My proposed fix is to clear the buffer_ordered flag after it has been
used, as in the following patch.

Signed-off-by: Neil Brown <neilb@suse.de>
Cc: <linux-ext4@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-08 09:22:44 -08:00
..
9p Convert ERR_PTR(PTR_ERR(p)) instances to ERR_CAST(p) 2008-02-07 08:42:26 -08:00
adfs mount options: fix adfs 2008-02-08 09:22:39 -08:00
affs mount options: fix affs 2008-02-08 09:22:39 -08:00
afs mount options: fix afs 2008-02-08 09:22:39 -08:00
autofs mount options: fix autofs 2008-02-08 09:22:40 -08:00
autofs4 mount options: fix autofs4 2008-02-08 09:22:39 -08:00
befs mount options: fix befs 2008-02-08 09:22:40 -08:00
bfs iget: stop BFS from using iget() and read_inode() 2008-02-07 08:42:27 -08:00
cifs iget: stop CIFS from using iget() and read_inode() 2008-02-07 08:42:27 -08:00
coda coda: convert struct class_device to struct device 2008-01-24 20:40:05 -08:00
configfs configfs: file.c fix possible recursive locking 2008-01-25 15:05:47 -08:00
cramfs fs/cramfs/inode.c: replace hardcoded value with preprocessor constant 2007-10-18 14:37:29 -07:00
debugfs libfs: allow error return from simple attributes 2008-02-08 09:22:34 -08:00
devpts mount options: fix devpts 2008-02-08 09:22:40 -08:00
dlm dlm: static initialization improvements 2008-01-30 11:04:43 -06:00
ecryptfs ecryptfs: check for existing key_tfm at mount time 2008-02-06 10:41:13 -08:00
efs iget: stop EFS from using iget() and read_inode() 2008-02-07 08:42:27 -08:00
exportfs exportfs: update documentation 2007-10-22 08:13:21 -07:00
ext2 mount options: fix ext2 2008-02-08 09:22:40 -08:00
ext3 ext3: replace all adds to little endians variables with le*_add_cpu 2008-02-08 09:22:32 -08:00
ext4 iget: stop EXT4 from using iget() and read_inode() 2008-02-07 08:42:27 -08:00
fat mount options: fix fat 2008-02-08 09:22:40 -08:00
freevxfs iget: stop FreeVXFS from using iget() and read_inode() 2008-02-07 08:42:28 -08:00
fuse mount options: fix fuse 2008-02-08 09:22:40 -08:00
gfs2 iget: use iget_failed() in GFS2 2008-02-07 08:42:27 -08:00
hfs hfs: update comment to reflect actual init and exit routines 2008-02-06 10:41:05 -08:00
hfsplus fs/hfsplus/unicode.c: fix uninitialized var warning 2008-02-08 09:22:36 -08:00
hostfs mount options: fix hostfs 2008-02-08 09:22:40 -08:00
hpfs mount options: fix hpfs 2008-02-08 09:22:40 -08:00
hppfs iget: stop HPPFS from using iget() and read_inode() 2008-02-07 08:42:29 -08:00
hugetlbfs mount options: fix hugetlbfs 2008-02-08 09:22:40 -08:00
isofs mount options: fix isofs 2008-02-08 09:22:40 -08:00
jbd ext3 can fail badly when device stops accepting BIO_RW_BARRIER requests 2008-02-08 09:22:44 -08:00
jbd2 BKL-removal: remove incorrect comment refering to lock_kernel() from jbd/jbd2 2008-02-06 10:41:20 -08:00
jffs2 Merge git://git.infradead.org/mtd-2.6 2008-02-07 10:20:31 -08:00
jfs BKL-removal: Implement a compat_ioctl handler for JFS 2008-02-07 13:45:29 -06:00
lockd NLM: tear down RPC clients in nlm_shutdown_hosts 2008-02-01 16:42:15 -05:00
minix iget: stop the MINIX filesystem from using iget() and read_inode() 2008-02-07 08:42:28 -08:00
msdos
ncpfs mount options: fix ncpfs 2008-02-08 09:22:40 -08:00
nfs NFS: Fix a potential file corruption issue when writing 2008-02-07 19:20:20 -05:00
nfs_common
nfsd Convert ERR_PTR(PTR_ERR(p)) instances to ERR_CAST(p) 2008-02-07 08:42:26 -08:00
nls sparse pointer use of zero as null 2007-10-18 14:37:31 -07:00
ntfs is_vmalloc_addr(): Check if an address is within the vmalloc boundaries 2008-02-05 09:44:14 -08:00
ocfs2 byteorder: move le32_add_cpu & friends from OCFS2 to core 2008-02-08 09:22:32 -08:00
openpromfs iget: stop OPENPROMFS from using iget() and read_inode() 2008-02-07 08:42:29 -08:00
partitions Block: Fix whole_disk attribute bug 2008-02-07 11:31:46 -08:00
proc procfs: constify function pointer tables 2008-02-08 09:22:38 -08:00
qnx4 iget: stop QNX4 from using iget() and read_inode() 2008-02-07 08:42:28 -08:00
ramfs Remove valueless definition of hard-selected RAMFS option 2007-10-17 08:42:56 -07:00
reiserfs mount options: fix reiserfs 2008-02-08 09:22:40 -08:00
romfs iget: stop ROMFS from using iget() and read_inode() 2008-02-07 08:42:28 -08:00
smbfs smbfs: fix calculation of kernel_recvmsg size parameter in smb_receive() 2008-02-06 10:41:02 -08:00
sysfs sysfs: remove BUG_ON() from sysfs_remove_group() 2008-02-07 11:31:46 -08:00
sysv iget: stop the SYSV filesystem from using iget() and read_inode() 2008-02-07 08:42:29 -08:00
udf mount options: fix udf 2008-02-08 09:22:41 -08:00
ufs drop linux/ufs_fs.h from userspace export and relocate it to fs/ufs/ufs_fs.h 2008-02-08 09:22:39 -08:00
vfat Convert ERR_PTR(PTR_ERR(p)) instances to ERR_CAST(p) 2008-02-07 08:42:26 -08:00
xfs Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-2.6 2008-02-07 19:12:12 -08:00
aio.c aio: negative offset should return -EINVAL 2008-02-08 09:22:33 -08:00
anon_inodes.c anon-inodes use open coded atomic_inc for the shared inode 2007-10-17 08:43:00 -07:00
attr.c VFS: make notify_change pass ATTR_KILL_S*ID to setattr operations 2007-10-18 14:37:22 -07:00
bad_inode.c iget: introduce a function to register iget failure 2008-02-07 08:42:26 -08:00
binfmt_aout.c aout: suppress A.OUT library support if !CONFIG_ARCH_SUPPORTS_AOUT 2008-02-08 09:22:30 -08:00
binfmt_elf.c Remove a.out interpreter support in ELF loader 2008-02-08 09:22:41 -08:00
binfmt_elf_fdpic.c pid namespaces: changes to show virtual ids to user 2007-10-19 11:53:40 -07:00
binfmt_em86.c Convert files to UTF-8 and some cleanups 2007-10-19 23:21:04 +02:00
binfmt_flat.c aout: remove unnecessary inclusions of {asm, linux}/a.out.h 2008-02-08 09:22:30 -08:00
binfmt_misc.c Convert files to UTF-8 and some cleanups 2007-10-19 23:21:04 +02:00
binfmt_script.c Convert files to UTF-8 and some cleanups 2007-10-19 23:21:04 +02:00
binfmt_som.c aout: remove unnecessary inclusions of {asm, linux}/a.out.h 2008-02-08 09:22:30 -08:00
bio.c __bio_clone: don't calculate hw/phys segment counts 2008-01-28 10:04:46 +01:00
block_dev.c kill an unused PTR_ERR in bdev_cache_init() 2008-02-06 10:41:06 -08:00
buffer.c buffer_head: fix private_list handling 2008-02-08 09:22:42 -08:00
char_dev.c fs/char_dev.c: chrdev_open marked static and removed from fs.h 2008-02-08 09:22:42 -08:00
compat.c fs: remove dead config CONFIG_HAS_COMPAT_EPOLL_EVENT symbol 2008-02-06 10:41:03 -08:00
compat_binfmt_elf.c x86: compat_binfmt_elf 2008-01-30 13:31:46 +01:00
compat_ioctl.c dm ioctl: move compat code 2008-02-08 02:09:56 +00:00
dcache.c inotify: remove debug code 2008-02-06 10:41:07 -08:00
dcookies.c
direct-io.c Pagecache zeroing: zero_user_segment, zero_user_segments and zero_user 2008-02-05 09:44:13 -08:00
dnotify.c
dquot.c quota: improve inode list scanning in add_dquot_ref() 2008-02-06 10:41:07 -08:00
drop_caches.c
eventfd.c fs/eventfd.c should #include <linux/syscalls.h> 2008-02-06 10:41:03 -08:00
eventpoll.c lockdep: annotate epoll 2008-02-05 09:44:07 -08:00
exec.c Allow executables larger than 2GB 2008-02-08 09:22:34 -08:00
fcntl.c fs: remove fastcall, it is always empty 2008-02-08 09:22:31 -08:00
fifo.c
file.c get rid of NR_OPEN and introduce a sysctl_nr_open 2008-02-06 10:41:06 -08:00
file_table.c fs: remove fastcall, it is always empty 2008-02-08 09:22:31 -08:00
filesystems.c
fs-writeback.c write_inode_now(): avoid unnecessary synchronous write 2008-02-08 09:22:34 -08:00
generic_acl.c
inode.c iget: remove iget() and the read_inode() super op as being obsolete 2008-02-07 08:42:29 -08:00
inotify.c inotify: remove debug code 2008-02-06 10:41:07 -08:00
inotify_user.c inotify: fix check for one-shot watches before destroying them 2008-02-08 09:22:22 -08:00
internal.h
ioctl.c VFS: factor out three helpers for FIBMAP/FIONBIO/FIOASYNC file ioctls 2008-02-07 08:42:16 -08:00
ioprio.c cfq-iosched: relax IOPRIO_CLASS_IDLE restrictions 2008-01-28 11:38:15 +01:00
Kconfig SUNRPC xptrdma: simplify build configuration 2008-02-07 19:58:08 -05:00
Kconfig.binfmt aout: suppress A.OUT library support if !CONFIG_ARCH_SUPPORTS_AOUT 2008-02-08 09:22:30 -08:00
libfs.c libfs: rename simple_attr_close to simple_attr_release 2008-02-08 09:22:34 -08:00
locks.c Pidns: make full use of xxx_vnr() calls 2008-02-08 09:22:29 -08:00
Makefile x86: compat_binfmt_elf Kconfig 2008-01-30 13:31:46 +01:00
mbcache.c fs: Fix to correct the mbcache entries counter 2007-10-25 15:18:29 -07:00
mpage.c Pagecache zeroing: zero_user_segment, zero_user_segments and zero_user 2008-02-05 09:44:13 -08:00
namei.c fs: remove fastcall, it is always empty 2008-02-08 09:22:31 -08:00
namespace.c reduce large do_mount stack usage with noinlines 2008-02-08 09:22:44 -08:00
nfsctl.c
no-block.c
open.c remove the unused exports of sys_open/sys_read 2008-02-08 09:22:36 -08:00
pipe.c BKL-Removal: convert pipe to use unlocked_ioctl too 2008-02-08 09:22:38 -08:00
pnode.c MNT_UNBINDABLE fix 2008-02-06 10:41:02 -08:00
pnode.h [PATCH] new helpers - collect_mounts() and release_collected_mounts() 2007-10-21 02:37:25 -04:00
posix_acl.c
quota.c Convert ERR_PTR(PTR_ERR(p)) instances to ERR_CAST(p) 2008-02-07 08:42:26 -08:00
quota_v1.c
quota_v2.c
read_write.c remove the unused exports of sys_open/sys_read 2008-02-08 09:22:36 -08:00
read_write.h
readdir.c Use mutex_lock_killable in vfs_readdir 2007-12-06 17:39:54 -05:00
select.c make sys_poll() wait at least timeout ms 2008-02-06 10:41:09 -08:00
seq_file.c
signalfd.c fs/signalfd.c should #include <linux/syscalls.h> 2008-02-06 10:41:03 -08:00
splice.c splice: always updated atime in direct splice 2008-02-01 09:26:32 +01:00
stack.c
stat.c
super.c mount options: add generic_show_options() 2008-02-08 09:22:39 -08:00
sync.c
timerfd.c timerfd: new timerfd API 2008-02-05 09:44:07 -08:00
utimes.c fs/utimes.c should #include <linux/syscalls.h> 2008-02-06 10:41:03 -08:00
xattr.c VFS: Reorder vfs_getxattr to avoid unnecessary calls to the LSM 2008-02-05 09:44:20 -08:00
xattr_acl.c