From: Mingming Cao <cmm@us.ibm.com>

Before we changed the per-filesystem reservations from a linked list to a
red-black tree, in order to speed up the linear search from the list head,
we keep the current(stale) reservation window as a reference pointer to
skip the nodes prior to the current/stale window node, when failed to
allocate a new window in current group and try to do allocation in next
group.  

With the red-black tree change, searching from the root is fast enough so
we don't need to keep the current window as a reference pointer to speed up
the search.Also, keep the curret/stale window in the tree while try to
allocate block in the rest groups could cause the window size being
possibly doubled incorrectly: currently the hit ratio bit was not cleared
until we find a new window, so when we continue to search a new window in
the next group, the current/stale window hit ratio bit is checked again,
and window size could be doubled again(wrong!).

This will cause too early to back to block allocation without reservation. 
This probably explain why we saw random write performance issue when the
filesystem is really full before: for every new block in request, we do
exaust the whole filesystem with wrong window size, and back to
non-reservation block allocation at last.

Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/ext3/balloc.c |    7 +++++++
 1 files changed, 7 insertions(+)

diff -puN fs/ext3/balloc.c~ext3-reservation-remove-stale-window-fix fs/ext3/balloc.c
--- 25/fs/ext3/balloc.c~ext3-reservation-remove-stale-window-fix	Mon Oct 18 16:46:02 2004
+++ 25-akpm/fs/ext3/balloc.c	Mon Oct 18 16:46:03 2004
@@ -934,6 +934,13 @@ found_rsv_window:
 	}
 	return 0;		/* succeed */
 failed:
+	/*
+	 * failed to find a new reservation window in the current
+	 * group, remove the current(stale) reservation window
+	 * if there is any
+	 */
+	if (!rsv_is_empty(&my_rsv->rsv_window))
+		rsv_window_remove(sb, my_rsv);
 	return -1;		/* failed */
 }
 
_