From: mingming cao Signed-off-by: Andrew Morton --- 25-akpm/fs/ext3/balloc.c | 21 +++++++++------------ 1 files changed, 9 insertions(+), 12 deletions(-) diff -puN fs/ext3/balloc.c~ext3_reservation_window_fix_fix fs/ext3/balloc.c --- 25/fs/ext3/balloc.c~ext3_reservation_window_fix_fix 2004-10-16 01:30:18.876630960 -0700 +++ 25-akpm/fs/ext3/balloc.c 2004-10-16 01:30:18.880630352 -0700 @@ -184,9 +184,10 @@ goal_in_my_reservation(struct reserve_wi * if the goal is not in any window. * Returns NULL if there are no windows or if all windows start after the goal. */ -static struct reserve_window_node *search_reserve_window(struct rb_node *n, +static struct reserve_window_node *search_reserve_window(struct rb_root *root, unsigned long goal) { + struct rb_node *n = root->rb_node; struct reserve_window_node *rsv; if (!n) @@ -822,10 +823,10 @@ static int alloc_new_reservation(struct start_block = goal + group_first_block; size = atomic_read(&my_rsv->rsv_goal_size); - /* if we have a old reservation, start the search from the old rsv */ if (!rsv_is_empty(&my_rsv->rsv_window)) { /* * if the old reservation is cross group boundary + * and if the goal is inside the old reservation window, * we will come here when we just failed to allocate from * the first part of the window. We still have another part * that belongs to the next group. In this case, there is no @@ -838,10 +839,10 @@ static int alloc_new_reservation(struct */ if ((my_rsv->rsv_start <= group_end_block) && - (my_rsv->rsv_end > group_end_block)) + (my_rsv->rsv_end > group_end_block) && + (start_block >= my_rsv->rsv_start)) return -1; - search_head = search_reserve_window(&my_rsv->rsv_node, start_block); if ((atomic_read(&my_rsv->rsv_alloc_hit) > (my_rsv->rsv_end - my_rsv->rsv_start + 1) / 2)) { /* @@ -855,14 +856,10 @@ static int alloc_new_reservation(struct atomic_set(&my_rsv->rsv_goal_size, size); } } - else { - /* - * we don't have a reservation, - * we set our goal(start_block) and - * the list head for the search - */ - search_head = search_reserve_window(fs_rsv_root->rb_node, start_block); - } + /* + * shift the search start to the window near the goal block + */ + search_head = search_reserve_window(fs_rsv_root, start_block); /* * find_next_reservable_window() simply finds a reservable window _