Revision ad576e63e0c8b274a8558b8e05a6d0526e804dc0 authored by Nick Piggin on 05 May 2005, 23:15:46 UTC, committed by Linus Torvalds on 05 May 2005, 23:36:40 UTC
When running
	fsstress -v -d $DIR/tmp -n 1000 -p 1000 -l 2
on an ext2 filesystem with 1024 byte block size, on SMP i386 with 4096 byte
page size over loopback to an image file on a tmpfs filesystem, I would
very quickly hit
	BUG_ON(!buffer_async_write(bh));
in fs/buffer.c:end_buffer_async_write

It seems that more than one request would be submitted for a given bh
at a time.

What would happen is the following:
2 threads doing __mpage_writepages on the same page.
Thread 1 - lock the page first, and enter __block_write_full_page.
Thread 1 - (eg.) mark_buffer_async_write on the first 2 buffers.
Thread 1 - set page writeback, unlock page.
Thread 2 - lock page, wait on page writeback
Thread 1 - submit_bh on the first 2 buffers.
=> both requests complete, none of the page buffers are async_write,
   end_page_writeback is called.
Thread 2 - wakes up. enters __block_write_full_page.
Thread 2 - mark_buffer_async_write on (eg.) the last buffer
Thread 1 - finds the last buffer has async_write set, submit_bh on that.
Thread 2 - submit_bh on the last buffer.
=> oops.

So change __block_write_full_page to explicitly keep track of the last bh
we need to issue, so we don't touch anything after issuing the last
request.

Signed-off-by: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
1 parent f3ddbdc
History
File Mode Size
adfs
affs
afs
autofs
autofs4
befs
bfs
cifs
coda
cramfs
debugfs
devfs
devpts
efs
exportfs
ext2
ext3
fat
freevxfs
hfs
hfsplus
hostfs
hpfs
hppfs
hugetlbfs
isofs
jbd
jffs
jffs2
jfs
lockd
minix
msdos
ncpfs
nfs
nfsd
nls
ntfs
openpromfs
partitions
proc
qnx4
ramfs
reiserfs
romfs
smbfs
sysfs
sysv
udf
ufs
umsdos
vfat
xfs
Kconfig -rw-r--r-- 63.6 KB
Kconfig.binfmt -rw-r--r-- 5.3 KB
Makefile -rw-r--r-- 3.0 KB
aio.c -rw-r--r-- 43.3 KB
attr.c -rw-r--r-- 5.0 KB
bad_inode.c -rw-r--r-- 2.8 KB
binfmt_aout.c -rw-r--r-- 14.8 KB
binfmt_elf.c -rw-r--r-- 45.2 KB
binfmt_elf_fdpic.c -rw-r--r-- 30.3 KB
binfmt_em86.c -rw-r--r-- 2.8 KB
binfmt_flat.c -rw-r--r-- 25.7 KB
binfmt_misc.c -rw-r--r-- 15.6 KB
binfmt_script.c -rw-r--r-- 2.7 KB
binfmt_som.c -rw-r--r-- 7.7 KB
bio.c -rw-r--r-- 25.4 KB
block_dev.c -rw-r--r-- 21.7 KB
buffer.c -rw-r--r-- 82.0 KB
char_dev.c -rw-r--r-- 9.2 KB
compat.c -rw-r--r-- 47.0 KB
compat_ioctl.c -rw-r--r-- 85.0 KB
dcache.c -rw-r--r-- 43.9 KB
dcookies.c -rw-r--r-- 6.3 KB
direct-io.c -rw-r--r-- 34.5 KB
dnotify.c -rw-r--r-- 4.3 KB
dquot.c -rw-r--r-- 51.6 KB
eventpoll.c -rw-r--r-- 44.0 KB
exec.c -rw-r--r-- 33.6 KB
fcntl.c -rw-r--r-- 13.1 KB
fifo.c -rw-r--r-- 3.2 KB
file.c -rw-r--r-- 5.5 KB
file_table.c -rw-r--r-- 5.9 KB
filesystems.c -rw-r--r-- 5.2 KB
fs-writeback.c -rw-r--r-- 19.7 KB
inode.c -rw-r--r-- 34.6 KB
ioctl.c -rw-r--r-- 3.9 KB
libfs.c -rw-r--r-- 12.9 KB
locks.c -rw-r--r-- 54.3 KB
mbcache.c -rw-r--r-- 18.3 KB
mpage.c -rw-r--r-- 20.8 KB
namei.c -rw-r--r-- 59.4 KB
namespace.c -rw-r--r-- 34.8 KB
nfsctl.c -rw-r--r-- 2.5 KB
open.c -rw-r--r-- 23.1 KB
pipe.c -rw-r--r-- 18.1 KB
posix_acl.c -rw-r--r-- 8.6 KB
quota.c -rw-r--r-- 8.8 KB
quota_v1.c -rw-r--r-- 5.7 KB
quota_v2.c -rw-r--r-- 20.1 KB
read_write.c -rw-r--r-- 15.3 KB
readdir.c -rw-r--r-- 6.7 KB
select.c -rw-r--r-- 12.2 KB
seq_file.c -rw-r--r-- 9.5 KB
stat.c -rw-r--r-- 9.2 KB
super.c -rw-r--r-- 19.9 KB
xattr.c -rw-r--r-- 10.3 KB
xattr_acl.c -rw-r--r-- 2.3 KB

back to top