From: gregkh@suse.de Date: Thu, 12 May 2005 04:19:38 +0000 (-0700) Subject: [PATCH] add ext3 patch. X-Git-Tag: v2.6.11.11~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3e1efadf000b4392643394ac83a23b0e33c6fed7;p=thirdparty%2Fkernel%2Fstable-queue.git [PATCH] add ext3 patch. --- diff --git a/queue/ext3-fix-race.patch b/queue/ext3-fix-race.patch new file mode 100644 index 00000000000..fa659d02a55 --- /dev/null +++ b/queue/ext3-fix-race.patch @@ -0,0 +1,82 @@ +From foo@baz Tue Apr 9 12:12:43 2002 +To: linux-kernel@vger.kernel.org +Date: 10 Mar 2005 08:44:10 -08:00 +From: cmm@us.ibm.com +Subject: [PATCH] ext3: fix race between ext3 make block reservation and reservation window discard + +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 +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +diff -Nru a/fs/ext3/balloc.c b/fs/ext3/balloc.c +--- a/fs/ext3/balloc.c 2005-05-11 21:18:50 -07:00 ++++ b/fs/ext3/balloc.c 2005-05-11 21:18:50 -07:00 +@@ -268,7 +268,8 @@ + + if (!rsv_is_empty(&rsv->rsv_window)) { + spin_lock(rsv_lock); +- rsv_window_remove(inode->i_sb, rsv); ++ if (!rsv_is_empty(&rsv->rsv_window)) ++ rsv_window_remove(inode->i_sb, rsv); + spin_unlock(rsv_lock); + } + }