mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-24 19:35:58 +00:00
fa0726854c
This patch fixed a race between ext3_discard_reservation() and ext3_try_to_allocate_with_rsv(). There is a window where ext3_discard_reservation will remove an already unlinked reservation window node from the filesystem reservation tree: It thinks the reservation is still linked in the filesystem reservation tree, but it is actually temperately removed from the tree by allocate_new_reservation() when it failed to make a new reservation from the current group and try to make a new reservation from next block group. Here is how it could happen: CPU 1 try to allocate a block in group1 with given reservation window my_rsv ext3_try_to_allocate_with_rsv(group ----copy reservation window my_rsv into local rsv_copy ext3_try_to_allocate(...rsv_copy) ----no free block in existing reservation window, ----need a new reservation window spin_lock(&rsv_lock); CPU 2 ext3_discard_reservation if (!rsv_is_empty() ----this is true spin_lock(&rsv_lock) ----waiting for thread 1 CPU 1: allocate_new_reservation failed to reserve blocks in this group remove the window from the tree rsv_window_remove(my_rsv) ----window node is unlinked from the tree here return -1 spin_unlock(&rsv_lock) ext3_try_to_allocate_with_rsv() failed in this group group++ CPU 2 spin_lock(&rsv_lock) succeed rsv_remove_window () ---------------break, trying to remove a unlinked node from the tree .... CPU 1: ext3_try_to_allocate_with_rsv(group, my_rsv) rsv_is_empty is true, need a new reservation window spin_lock(&rsv_lock); ^--------------- spinning forever We need to re-check whether the reservation window is still linked to the tree after grab the rsv_lock spin lock in ext3_discard_reservation, to prevent panic in rsv_remove_window->rb_erase. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Chris Wright <chrisw@osdl.org> |
||
---|---|---|
.. | ||
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 | ||
aio.c | ||
attr.c | ||
bad_inode.c | ||
binfmt_aout.c | ||
binfmt_elf.c | ||
binfmt_elf_fdpic.c | ||
binfmt_em86.c | ||
binfmt_flat.c | ||
binfmt_misc.c | ||
binfmt_script.c | ||
binfmt_som.c | ||
bio.c | ||
block_dev.c | ||
buffer.c | ||
char_dev.c | ||
compat.c | ||
compat_ioctl.c | ||
dcache.c | ||
dcookies.c | ||
direct-io.c | ||
dnotify.c | ||
dquot.c | ||
eventpoll.c | ||
exec.c | ||
fcntl.c | ||
fifo.c | ||
file.c | ||
file_table.c | ||
filesystems.c | ||
fs-writeback.c | ||
inode.c | ||
ioctl.c | ||
Kconfig | ||
Kconfig.binfmt | ||
libfs.c | ||
locks.c | ||
Makefile | ||
mbcache.c | ||
mpage.c | ||
namei.c | ||
namespace.c | ||
nfsctl.c | ||
open.c | ||
pipe.c | ||
posix_acl.c | ||
quota.c | ||
quota_v1.c | ||
quota_v2.c | ||
read_write.c | ||
readdir.c | ||
select.c | ||
seq_file.c | ||
stat.c | ||
super.c | ||
xattr.c | ||
xattr_acl.c |