From: Stephen Tweedie <sct@redhat.com>

Split the "reserve_window" struct into two parts: a small "reserve_window"
describing the reservation itself, and a "reserve_window_node" which contains
the reservation plus all the data needed to link it into the per-sb
reservations tree.  

Signed-off-by: Stephen Tweedie <sct@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/ext3/balloc.c           |   80 ++++++++++++++++++-------------------
 25-akpm/include/linux/ext3_fs.h    |    2 
 25-akpm/include/linux/ext3_fs_i.h  |   13 ++++--
 25-akpm/include/linux/ext3_fs_sb.h |    2 
 4 files changed, 53 insertions(+), 44 deletions(-)

diff -puN fs/ext3/balloc.c~ext3-reservations-split-the-reserve_window-struct-into-two fs/ext3/balloc.c
--- 25/fs/ext3/balloc.c~ext3-reservations-split-the-reserve_window-struct-into-two	Tue Sep  7 15:38:07 2004
+++ 25-akpm/fs/ext3/balloc.c	Tue Sep  7 15:38:07 2004
@@ -115,7 +115,7 @@ static void __rsv_window_dump(struct rb_
 			      const char *fn)
 {
 	struct rb_node *n;
-	struct reserve_window *rsv, *prev;
+	struct reserve_window_node *rsv, *prev;
 	int bad;
 
 restart:
@@ -125,7 +125,7 @@ restart:
 
 	printk("Block Allocation Reservation Windows Map (%s):\n", fn);
 	while (n) {
-		rsv = list_entry(n, struct reserve_window, rsv_node);
+		rsv = list_entry(n, struct reserve_window_node, rsv_node);
 		if (verbose)
 			printk("reservation window 0x%p "
 			       "start:  %d, end:  %d\n",
@@ -170,11 +170,11 @@ goal_in_my_reservation(struct reserve_wi
 				group * EXT3_BLOCKS_PER_GROUP(sb);
 	group_last_block = group_first_block + EXT3_BLOCKS_PER_GROUP(sb) - 1;
 
-	if ((rsv->rsv_start > group_last_block) ||
-	    (rsv->rsv_end < group_first_block))
+	if ((rsv->_rsv_start > group_last_block) ||
+	    (rsv->_rsv_end < group_first_block))
 		return 0;
-	if ((goal >= 0) && ((goal + group_first_block < rsv->rsv_start)
-		|| (goal + group_first_block > rsv->rsv_end)))
+	if ((goal >= 0) && ((goal + group_first_block < rsv->_rsv_start)
+		|| (goal + group_first_block > rsv->_rsv_end)))
 		return 0;
 	return 1;
 }
@@ -184,18 +184,18 @@ 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 *search_reserve_window(struct rb_root *root,
-						    unsigned long goal)
+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 *rsv;
+	struct reserve_window_node *rsv;
 
 	if (!n)
 		return NULL;
 
 	while (n)
 	{
-		rsv = rb_entry(n, struct reserve_window, rsv_node);
+		rsv = rb_entry(n, struct reserve_window_node, rsv_node);
 
 		if (goal < rsv->rsv_start)
 			n = n->rb_left;
@@ -212,13 +212,13 @@ static struct reserve_window *search_res
 	 */
 	if (rsv->rsv_start > goal) {
 		n = rb_prev(&rsv->rsv_node);
-		rsv = rb_entry(n, struct reserve_window, rsv_node);
+		rsv = rb_entry(n, struct reserve_window_node, rsv_node);
 	}
 	return rsv;
 }
 
 void rsv_window_add(struct super_block *sb,
-		    struct reserve_window *rsv)
+		    struct reserve_window_node *rsv)
 {
 	struct rb_root *root = &EXT3_SB(sb)->s_rsv_window_root;
 	struct rb_node *node = &rsv->rsv_node;
@@ -226,12 +226,12 @@ void rsv_window_add(struct super_block *
 
 	struct rb_node ** p = &root->rb_node;
 	struct rb_node * parent = NULL;
-	struct reserve_window *this;
+	struct reserve_window_node *this;
 
 	while (*p)
 	{
 		parent = *p;
-		this = rb_entry(parent, struct reserve_window, rsv_node);
+		this = rb_entry(parent, struct reserve_window_node, rsv_node);
 
 		if (start < this->rsv_start)
 			p = &(*p)->rb_left;
@@ -246,7 +246,7 @@ void rsv_window_add(struct super_block *
 }
 
 static void rsv_window_remove(struct super_block *sb,
-			      struct reserve_window *rsv)
+			      struct reserve_window_node *rsv)
 {
 	rsv->rsv_start = 0;
 	rsv->rsv_end = 0;
@@ -257,16 +257,16 @@ static void rsv_window_remove(struct sup
 static inline int rsv_is_empty(struct reserve_window *rsv)
 {
 	/* a valid reservation end block could not be 0 */
-	return (rsv->rsv_end == 0);
+	return (rsv->_rsv_end == 0);
 }
 
 void ext3_discard_reservation(struct inode *inode)
 {
 	struct ext3_inode_info *ei = EXT3_I(inode);
-	struct reserve_window *rsv = &ei->i_rsv_window;
+	struct reserve_window_node *rsv = &ei->i_rsv_window;
 	spinlock_t *rsv_lock = &EXT3_SB(inode->i_sb)->s_rsv_window_lock;
 
-	if (!rsv_is_empty(rsv)) {
+	if (!rsv_is_empty(&rsv->rsv_window)) {
 		spin_lock(rsv_lock);
 		rsv_window_remove(inode->i_sb, rsv);
 		spin_unlock(rsv_lock);
@@ -609,12 +609,12 @@ ext3_try_to_allocate(struct super_block 
 		group_first_block =
 			le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) +
 			group * EXT3_BLOCKS_PER_GROUP(sb);
-		if (my_rsv->rsv_start >= group_first_block)
-			start = my_rsv->rsv_start - group_first_block;
+		if (my_rsv->_rsv_start >= group_first_block)
+			start = my_rsv->_rsv_start - group_first_block;
 		else
 			/* reservation window cross group boundary */
 			start = 0;
-		end = my_rsv->rsv_end - group_first_block + 1;
+		end = my_rsv->_rsv_end - group_first_block + 1;
 		if (end > EXT3_BLOCKS_PER_GROUP(sb))
 			/* reservation window crosses group boundary */
 			end = EXT3_BLOCKS_PER_GROUP(sb);
@@ -660,8 +660,6 @@ repeat:
 			goto fail_access;
 		goto repeat;
 	}
-	if (my_rsv)
-		my_rsv->rsv_alloc_hit++;
 	return goal;
 fail_access:
 	return -1;
@@ -702,13 +700,13 @@ fail_access:
  *	on succeed, it returns the reservation window to be appended to.
  *	failed, return NULL.
  */
-static struct reserve_window *find_next_reservable_window(
-				struct reserve_window *search_head,
+static struct reserve_window_node *find_next_reservable_window(
+				struct reserve_window_node *search_head,
 				unsigned long size, int *start_block,
 				int last_block)
 {
 	struct rb_node *next;
-	struct reserve_window *rsv, *prev;
+	struct reserve_window_node *rsv, *prev;
 	int cur;
 
 	/* TODO: make the start of the reservation window byte-aligned */
@@ -736,7 +734,7 @@ static struct reserve_window *find_next_
 
 		prev = rsv;
 		next = rb_next(&rsv->rsv_node);
-		rsv = list_entry(next, struct reserve_window, rsv_node);
+		rsv = list_entry(next, struct reserve_window_node, rsv_node);
 
 		/*
 		 * Reached the last reservation, we can just append to the
@@ -813,15 +811,15 @@ static struct reserve_window *find_next_
  *	@group: the group we are trying to allocate in
  *	@bitmap_bh: the block group block bitmap
  */
-static int alloc_new_reservation(struct reserve_window *my_rsv,
+static int alloc_new_reservation(struct reserve_window_node *my_rsv,
 		int goal, struct super_block *sb,
 		unsigned int group, struct buffer_head *bitmap_bh)
 {
-	struct reserve_window *search_head;
+	struct reserve_window_node *search_head;
 	int group_first_block, group_end_block, start_block;
 	int first_free_block;
 	int reservable_space_start;
-	struct reserve_window *prev_rsv;
+	struct reserve_window_node *prev_rsv;
 	struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root;
 	unsigned long size;
 
@@ -836,7 +834,7 @@ static int alloc_new_reservation(struct 
 
 	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)) {
+	if (!rsv_is_empty(&my_rsv->rsv_window)) {
 		/*
 		 * if the old reservation is cross group boundary
 		 * we will come here when we just failed to allocate from
@@ -941,7 +939,7 @@ found_rsv_window:
 	 * same place, just update the new start and new end.
 	 */
 	if (my_rsv != prev_rsv)  {
-		if (!rsv_is_empty(my_rsv))
+		if (!rsv_is_empty(&my_rsv->rsv_window))
 			rsv_window_remove(sb, my_rsv);
 	}
 	my_rsv->rsv_start = reservable_space_start;
@@ -978,7 +976,7 @@ failed:
 static int
 ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle,
 			unsigned int group, struct buffer_head *bitmap_bh,
-			int goal, struct reserve_window * my_rsv,
+			int goal, struct reserve_window_node * my_rsv,
 			int *errp)
 {
 	spinlock_t *rsv_lock;
@@ -1037,8 +1035,9 @@ ext3_try_to_allocate_with_rsv(struct sup
 	 * then we could go to allocate from the reservation window directly.
 	 */
 	while (1) {
-		if (rsv_is_empty(my_rsv) || (ret < 0) ||
-			!goal_in_my_reservation(my_rsv, goal, group, sb)) {
+		if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) ||
+			!goal_in_my_reservation(&my_rsv->rsv_window,
+						goal, group, sb)) {
 			spin_lock(rsv_lock);
 			ret = alloc_new_reservation(my_rsv, goal, sb,
 							group, bitmap_bh);
@@ -1046,16 +1045,19 @@ ext3_try_to_allocate_with_rsv(struct sup
 			if (ret < 0)
 				break;			/* failed */
 
-			if (!goal_in_my_reservation(my_rsv, goal, group, sb))
+			if (!goal_in_my_reservation(&my_rsv->rsv_window,
+						    goal, group, sb))
 				goal = -1;
 		}
 		if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb))
 			|| (my_rsv->rsv_end < group_first_block))
 			BUG();
 		ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal,
-					my_rsv);
-		if (ret >= 0)
+					   &my_rsv->rsv_window);
+		if (ret >= 0) {
+			my_rsv->rsv_alloc_hit++;
 			break;				/* succeed */
+		}
 	}
 out:
 	if (ret >= 0) {
@@ -1129,7 +1131,7 @@ int ext3_new_block(handle_t *handle, str
 	struct ext3_group_desc *gdp;
 	struct ext3_super_block *es;
 	struct ext3_sb_info *sbi;
-	struct reserve_window *my_rsv = NULL;
+	struct reserve_window_node *my_rsv = NULL;
 #ifdef EXT3FS_DEBUG
 	static int goal_hits, goal_attempts;
 #endif
diff -puN include/linux/ext3_fs.h~ext3-reservations-split-the-reserve_window-struct-into-two include/linux/ext3_fs.h
--- 25/include/linux/ext3_fs.h~ext3-reservations-split-the-reserve_window-struct-into-two	Tue Sep  7 15:38:07 2004
+++ 25-akpm/include/linux/ext3_fs.h	Tue Sep  7 15:38:07 2004
@@ -692,7 +692,7 @@ extern struct ext3_group_desc * ext3_get
 						    unsigned int block_group,
 						    struct buffer_head ** bh);
 extern int ext3_should_retry_alloc(struct super_block *sb, int *retries);
-extern void rsv_window_add(struct super_block *sb, struct reserve_window *rsv);
+extern void rsv_window_add(struct super_block *sb, struct reserve_window_node *rsv);
 
 /* dir.c */
 extern int ext3_check_dir_entry(const char *, struct inode *,
diff -puN include/linux/ext3_fs_i.h~ext3-reservations-split-the-reserve_window-struct-into-two include/linux/ext3_fs_i.h
--- 25/include/linux/ext3_fs_i.h~ext3-reservations-split-the-reserve_window-struct-into-two	Tue Sep  7 15:38:07 2004
+++ 25-akpm/include/linux/ext3_fs_i.h	Tue Sep  7 15:38:07 2004
@@ -20,13 +20,20 @@
 #include <linux/rbtree.h>
 
 struct reserve_window {
+	__u32			_rsv_start;	/* First byte reserved */
+	__u32			_rsv_end;	/* Last byte reserved or 0 */
+};
+
+struct reserve_window_node {
 	struct rb_node	 	rsv_node;
-	__u32			rsv_start;	/* First byte reserved */
-	__u32			rsv_end;	/* Last byte reserved or 0 */
 	atomic_t		rsv_goal_size;
 	__u32			rsv_alloc_hit;
+	struct reserve_window	rsv_window;
 };
 
+#define rsv_start rsv_window._rsv_start
+#define rsv_end rsv_window._rsv_end
+
 /*
  * third extended file system inode data in memory
  */
@@ -67,7 +74,7 @@ struct ext3_inode_info {
 	 */
 	__u32	i_next_alloc_goal;
 	/* block reservation window */
-	struct reserve_window i_rsv_window;
+	struct reserve_window_node i_rsv_window;
 
 	__u32	i_dir_start_lookup;
 #ifdef CONFIG_EXT3_FS_XATTR
diff -puN include/linux/ext3_fs_sb.h~ext3-reservations-split-the-reserve_window-struct-into-two include/linux/ext3_fs_sb.h
--- 25/include/linux/ext3_fs_sb.h~ext3-reservations-split-the-reserve_window-struct-into-two	Tue Sep  7 15:38:07 2004
+++ 25-akpm/include/linux/ext3_fs_sb.h	Tue Sep  7 15:38:07 2004
@@ -63,7 +63,7 @@ struct ext3_sb_info {
 	/* root of the per fs reservation window tree */
 	spinlock_t s_rsv_window_lock;
 	struct rb_root s_rsv_window_root;
-	struct reserve_window s_rsv_window_head;
+	struct reserve_window_node s_rsv_window_head;
 
 	/* Journaling */
 	struct inode * s_journal_inode;
_