aha/fs
Jan Kara 535ee2fbf7 buffer_head: fix private_list handling
There are two possible races in handling of private_list in buffer cache.

1) When fsync_buffers_list() processes a private_list, it clears
   b_assoc_mapping and moves buffer to its private list.  Now
   drop_buffers() comes, sees a buffer is on list so it calls
   __remove_assoc_queue() which complains about b_assoc_mapping being
   cleared (as it cannot propagate possible IO error).  This race has been
   actually observed in the wild.

2) When fsync_buffers_list() processes a private_list,
   mark_buffer_dirty_inode() can be called on bh which is already on the
   private list of fsync_buffers_list().  As buffer is on some list (note
   that the check is performed without private_lock), it is not readded to
   the mapping's private_list and after fsync_buffers_list() finishes, we
   have a dirty buffer which should be on private_list but it isn't.  This
   race has not been reported, probably because most (but not all) callers
   of mark_buffer_dirty_inode() hold i_mutex and thus are serialized with
   fsync().

Fix these issues by not clearing b_assoc_map when fsync_buffers_list()
moves buffer to a dedicated list and by reinserting buffer in private_list
when it is found dirty after we have submitted buffer for IO.  We also
change the tests whether a buffer is on a private list from
!list_empty(&bh->b_assoc_buffers) to bh->b_assoc_map so that they are
single word reads and hence lockless checks are safe.

Signed-off-by: Jan Kara <jack@suse.cz>
Cc: Nick Piggin <npiggin@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-02-08 09:22:42 -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
configfs
cramfs
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
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 make jbd/journal.c:__journal_abort_hard() static 2008-02-06 10:41:20 -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
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
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
attr.c
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
binfmt_em86.c
binfmt_flat.c aout: remove unnecessary inclusions of {asm, linux}/a.out.h 2008-02-08 09:22:30 -08:00
binfmt_misc.c
binfmt_script.c
binfmt_som.c aout: remove unnecessary inclusions of {asm, linux}/a.out.h 2008-02-08 09:22:30 -08:00
bio.c
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 Kobject: rename kobject_init_ng() to kobject_init() 2008-01-24 20:40:38 -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
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
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 mount options: add generic_show_options() 2008-02-08 09:22:39 -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
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
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