--- linux-2.6.8.1-mm1/fs/ext3/balloc.c.=K0006=.orig +++ linux-2.6.8.1-mm1/fs/ext3/balloc.c @@ -20,6 +20,12 @@ #include #include +#if 0 +#define dprintk(msg...) printk(msg) +#else +#define dprintk(msg...) do { } while(0) +#endif + /* * balloc.c contains the blocks allocation and deallocation routines */ @@ -110,7 +116,7 @@ error_out: * we could easily switch to that without changing too much * code. */ -#if 0 +#if 1 static void __rsv_window_dump(struct rb_root *root, int verbose, const char *fn) { @@ -213,6 +219,17 @@ static struct reserve_window_node *searc if (rsv->rsv_start > goal) { n = rb_prev(&rsv->rsv_node); rsv = rb_entry(n, struct reserve_window_node, rsv_node); + if (rsv->rsv_start > goal) + BUG(); + } + { + struct reserve_window_node *next; + n = rb_next(&rsv->rsv_node); + if (n) { + next = rb_entry(n, struct reserve_window_node, rsv_node); + if (next->rsv_start < goal) + BUG(); + } } return rsv; } @@ -227,6 +244,8 @@ void rsv_window_add(struct super_block * struct rb_node ** p = &root->rb_node; struct rb_node * parent = NULL; struct reserve_window_node *this; + + static int debug_counter = 0; while (*p) { @@ -237,12 +256,29 @@ void rsv_window_add(struct super_block * p = &(*p)->rb_left; else if (start > this->rsv_end) p = &(*p)->rb_right; - else + else { + /* We should never be adding a reservation which + * overlaps an existing one */ + printk(KERN_ALERT + "Whoops, got a reservation overlap:\n" + "old %p start %u end %u goal_size %d\n" + "new %p start %u end %u goal_size %d\n", + this, this->rsv_start, this->rsv_end, + atomic_read(&this->rsv_goal_size), + rsv, rsv->rsv_start, rsv->rsv_end, + atomic_read(&rsv->rsv_goal_size)); + rsv_window_dump(root, 1); BUG(); + } } rb_link_node(node, parent, p); rb_insert_color(node, root); + + if (++debug_counter > 1000) { + rsv_window_dump(root, 0); + debug_counter = 0; + } } static void rsv_window_remove(struct super_block *sb, @@ -716,6 +752,9 @@ static struct reserve_window_node *find_ if (!rsv) return NULL; + dprintk(KERN_DEBUG "%s: starting from 0x%p @ %d, looking for %d\n", + __FUNCTION__, search_head, rsv->rsv_start, cur); + while (1) { if (cur <= rsv->rsv_end) cur = rsv->rsv_end + 1; @@ -735,6 +774,8 @@ static struct reserve_window_node *find_ prev = rsv; next = rb_next(&rsv->rsv_node); rsv = list_entry(next, struct reserve_window_node, rsv_node); + dprintk(KERN_DEBUG "%s: looking at 0x%p [%d]\n", + __FUNCTION__, rsv, rsv->rsv_start); /* * Reached the last reservation, we can just append to the @@ -856,6 +897,8 @@ static int alloc_new_reservation(struct if (my_rsv->rsv_end + 1 > start_block) start_block = my_rsv->rsv_end + 1; search_head = my_rsv; + dprintk(KERN_DEBUG "%s: search starting from 0x%p (@%d)\n", + __FUNCTION__, search_head, search_head->rsv_start); if ((atomic_read(&my_rsv->rsv_alloc_hit) > (my_rsv->rsv_end - my_rsv->rsv_start + 1) / 2)) { /* @@ -876,6 +919,8 @@ static int alloc_new_reservation(struct * the list head for the search */ search_head = search_reserve_window(fs_rsv_root, start_block); + dprintk(KERN_DEBUG "%s: search returned 0x%p\n", + __FUNCTION__, search_head); } /* @@ -888,6 +933,9 @@ static int alloc_new_reservation(struct retry: prev_rsv = find_next_reservable_window(search_head, size, &start_block, group_end_block); + dprintk(KERN_DEBUG "%s: found window 0x%p, block %d\n", + __FUNCTION__, prev_rsv, start_block); + if (prev_rsv == NULL) goto failed; reservable_space_start = start_block; @@ -929,6 +977,8 @@ retry: * we also shift the list head to where we stopped last time */ search_head = prev_rsv; + dprintk (KERN_DEBUG "%s: retrying from 0x%p @%d\n", + __FUNCTION__, prev_rsv, prev_rsv->rsv_start); goto retry; found_rsv_window: @@ -1062,8 +1112,12 @@ ext3_try_to_allocate_with_rsv(struct sup goal = -1; } if ((rsv_copy._rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) - || (rsv_copy._rsv_end < group_first_block)) + || (rsv_copy._rsv_end < group_first_block)) { + printk("Whoops, invalid reservation %p (%d to %d)\n", + my_rsv, my_rsv->rsv_start, my_rsv->rsv_end); + rsv_window_dump(&EXT3_SB(sb)->s_rsv_window_root, 1); BUG(); + } ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, &rsv_copy); if (ret >= 0) {