diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.20.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.20.patch
index f2108d0df0fedfc0528352779ef7c4e50bd24f0c..8916f0f414a8dcacdd6345d2ad514c3a1a646175 100644
--- a/lustre/kernel_patches/patches/ext3-extents-2.4.20.patch
+++ b/lustre/kernel_patches/patches/ext3-extents-2.4.20.patch
@@ -1,8 +1,8 @@
 Index: linux-2.4.24/fs/ext3/extents.c
 ===================================================================
 --- linux-2.4.24.orig/fs/ext3/extents.c	2003-01-30 13:24:37.000000000 +0300
-+++ linux-2.4.24/fs/ext3/extents.c	2004-01-28 20:01:16.000000000 +0300
-@@ -0,0 +1,2254 @@
++++ linux-2.4.24/fs/ext3/extents.c	2004-01-29 16:18:31.000000000 +0300
+@@ -0,0 +1,2302 @@
 +/*
 + * Copyright (C) 2003 Alex Tomas <alex@clusterfs.com>
 + *
@@ -88,13 +88,18 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +				struct ext3_extents_tree *tree,
 +				struct ext3_ext_path *path)
 +{
++	int err;
++
 +	if (path->p_bh) {
 +		/* path points to block */
-+		return ext3_journal_get_write_access(handle, path->p_bh);
++		err = ext3_journal_get_write_access(handle, path->p_bh);
++	} else {
++		/* path points to leaf/index in inode body */
++		err = ext3_ext_get_access_for_root(handle, tree);
 +	}
-+
-+	/* path points to leaf/index in inode body */
-+	return ext3_ext_get_access_for_root(handle, tree);
++	if (err)
++		printk("err=%d (%s:%d)\n", err, __FILE__, __LINE__);
++	return err;
 +}
 +
 +/*
@@ -106,13 +111,17 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree,
 +				struct ext3_ext_path *path)
 +{
++	int err;
 +	if (path->p_bh) {
 +		/* path points to block */
-+		return ext3_journal_dirty_metadata(handle, path->p_bh);
++		err =ext3_journal_dirty_metadata(handle, path->p_bh);
++	} else {
++		/* path points to leaf/index in inode body */
++		err = ext3_ext_mark_root_dirty(handle, tree);
 +	}
-+
-+	/* path points to leaf/index in inode body */
-+	return ext3_ext_mark_root_dirty(handle, tree);
++	if (err)
++		printk("err=%d (%s:%d)\n", err, __FILE__, __LINE__);
++	return err;
 +}
 +
 +static int inline
@@ -148,6 +157,13 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +	return newblock;
 +}
 +
++static inline void ext3_ext_tree_changed(struct ext3_extents_tree *tree)
++{
++	struct ext3_extent_header *neh;
++	neh = EXT_ROOT_HDR(tree);
++	neh->e_generation++;
++}
++
 +static inline int ext3_ext_space_block(struct ext3_extents_tree *tree)
 +{
 +	int size;
@@ -614,10 +630,11 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +	path[depth].p_ext++;
 +	while (path[depth].p_ext <=
 +			EXT_MAX_EXTENT(path[depth].p_hdr)) {
-+		ext_debug(tree, "move %d:%d:%d in new leaf\n",
++		ext_debug(tree, "move %d:%d:%d in new leaf %lu\n",
 +				path[depth].p_ext->e_block,
 +				path[depth].p_ext->e_start,
-+				path[depth].p_ext->e_num);
++				path[depth].p_ext->e_num,
++				newblock);
 +		memmove(ex++, path[depth].p_ext++,
 +				sizeof(struct ext3_extent));
 +		neh->e_num++;
@@ -633,10 +650,10 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +
 +	/* correct old leaf */
 +	if (m) {
-+		if ((err = ext3_ext_get_access(handle, tree, path)))
++		if ((err = ext3_ext_get_access(handle, tree, path + depth)))
 +			goto cleanup;
 +		path[depth].p_hdr->e_num -= m;
-+		if ((err = ext3_ext_dirty(handle, tree, path)))
++		if ((err = ext3_ext_dirty(handle, tree, path + depth)))
 +			goto cleanup;
 +		
 +	}
@@ -682,9 +699,9 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +		EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) ==
 +				EXT_LAST_INDEX(path[i].p_hdr));
 +		while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) {
-+			ext_debug(tree, "%d: move %d:%d in new index\n",
++			ext_debug(tree, "%d: move %d:%d in new index %lu\n",
 +					i, path[i].p_idx->e_block,
-+					path[i].p_idx->e_leaf);
++					path[i].p_idx->e_leaf, newblock);
 +			memmove(++fidx, path[i].p_idx++,
 +					sizeof(struct ext3_extent_idx));
 +			neh->e_num++;
@@ -1041,7 +1058,8 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +			return err;
 +		ex->e_num += newext->e_num;
 +		err = ext3_ext_dirty(handle, tree, path + depth);
-+		return err;
++		ext3_ext_tree_changed(tree);
++		goto out;
 +	}
 +
 +repeat:
@@ -1137,7 +1155,8 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +		ext3_ext_drop_refs(npath);
 +		kfree(npath);
 +	}
-+		
++out:	
++	ext3_ext_tree_changed(tree);
 +	return err;
 +}
 +
@@ -1147,6 +1166,7 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +	struct ext3_ext_path *path = NULL;
 +	struct ext3_extent *ex, cbex;
 +	unsigned long next, start = 0, end = 0;
++	unsigned long last = block + num;
 +	int depth, exists, err = 0;
 +
 +	EXT_ASSERT(tree);
@@ -1154,11 +1174,13 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +	EXT_ASSERT(tree->inode);
 +	EXT_ASSERT(tree->root);
 +
-+	while (num > 0 && block != 0xfffffffff) {
++	while (block < last && block != 0xfffffffff) {
++		num = last - block;
 +		/* find extent for this block */
 +		path = ext3_ext_find_extent(tree, block, path);
 +		if (IS_ERR(path)) {
 +			err = PTR_ERR(path);
++			path = NULL;
 +			break;
 +		}
 +
@@ -1171,58 +1193,60 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +			/* there is no extent yet, so try to allocate
 +			 * all requested space */
 +			start = block;
-+			end = block + num - 1;
++			end = block + num;
 +		} else if (ex->e_block > block) {
 +			/* need to allocate space before found extent */
 +			start = block;
-+			end = ex->e_block - 1;
-+			if (block + num - 1 < end)
-+				end = block + num - 1;
++			end = ex->e_block;
++			if (block + num < end)
++				end = block + num;
 +		} else if (block >= ex->e_block + ex->e_num) {
 +			/* need to allocate space after found extent */
 +			start = block;
-+			end = block + num - 1;
++			end = block + num;
 +			if (end >= next)
-+				end = next - 1;
++				end = next;
 +		} else if (block >= ex->e_block) {
 +			/* 
 +			 * some part of requested space is covered
 +			 * by found extent
 +			 */
 +			start = block;
-+			end = ex->e_block + ex->e_num - 1;
-+			if (block + num - 1 < end)
-+				end = block + num - 1;
++			end = ex->e_block + ex->e_num;
++			if (block + num < end)
++				end = block + num;
 +			exists = 1;
 +		} else {
 +			BUG();
 +		}
++		EXT_ASSERT(end > start);
 +
 +		if (!exists) {
 +			cbex.e_block = start;
-+			cbex.e_num = end - start + 1;
++			cbex.e_num = end - start;
 +			cbex.e_start = 0;
 +		} else
 +			cbex = *ex;
 +
 +		err = func(tree, path, &cbex, exists);
++		ext3_ext_drop_refs(path);
++
 +		if (err < 0)
 +			break;
-+
-+		if (err == EXT_BREAK) {
++		if (err == EXT_REPEAT)
++			continue;
++		else if (err == EXT_BREAK) {
 +			err = 0;
 +			break;
 +		}
 +
 +		if (EXT_DEPTH(tree) != depth) {
 +			/* depth was changed. we have to realloc path */
-+			ext3_ext_drop_refs(path);
 +			kfree(path);
 +			path = NULL;
 +		}
 +
-+		block += cbex.e_num;
-+		num -= cbex.e_num;
++		block = cbex.e_block + cbex.e_num;
 +	}
 +
 +	if (path) {
@@ -1724,6 +1748,7 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +			err = ext3_ext_dirty(handle, tree, path);
 +		}
 +	}
++	ext3_ext_tree_changed(tree);
 +
 +	kfree(path);
 +	ext3_journal_stop(handle, inode);
@@ -1772,8 +1797,7 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +static int ext3_mark_buffer_dirty(handle_t *handle, void *buffer)
 +{
 +	struct inode *inode = buffer;
-+	ext3_mark_inode_dirty(handle, inode);
-+	return 0;
++	return ext3_mark_inode_dirty(handle, inode);
 +}
 +
 +static int ext3_ext_mergable(struct ext3_extent *ex1,
@@ -1914,21 +1938,35 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +	loff_t new_i_size;
 +	handle_t *handle;
 +	unsigned long pblock;
++	unsigned long tgen;
 +
 +	if (exist)
 +		return EXT_CONTINUE;
 +
++	tgen = EXT_GENERATION(tree);
 +	count = ext3_ext_calc_credits_for_insert(tree, path);
++	up_write(&EXT3_I(inode)->truncate_sem);
++
 +	handle = ext3_journal_start(inode, count + EXT3_ALLOC_NEEDED + 1);
-+	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
++		down_write(&EXT3_I(inode)->truncate_sem);
 +		return PTR_ERR(handle);
++	}
 +
++	if (tgen != EXT_GENERATION(tree)) {
++		/* the tree has changed. so path can be invalid at moment */
++		ext3_journal_stop(handle, inode);
++		down_write(&EXT3_I(inode)->truncate_sem);
++		return EXT_REPEAT;
++	}
++
++	down_write(&EXT3_I(inode)->truncate_sem);
 +	goal = ext3_ext_find_goal(inode, path);
 +	count = newex->e_num;
 +	pblock = ext3_new_blocks(handle, inode, &count, goal, &err);
++	if (!pblock)
++		goto out;
 +	EXT_ASSERT(count <= newex->e_num);
-+	/* FIXME: error handling here */
-+	EXT_ASSERT(err == 0);
 +
 +	/* insert new extent */
 +	newex->e_start = pblock;
@@ -2004,6 +2042,7 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +	path = ext3_ext_find_extent(&tree, iblock, NULL);
 +	if (IS_ERR(path)) {
 +		err = PTR_ERR(path);
++		path = NULL;
 +		goto out2;
 +	}
 +
@@ -2220,6 +2259,9 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +{
 +	int err = 0;
 +
++	if (!(EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL))
++		return -EINVAL;
++
 +	if (cmd == EXT3_IOC_GET_EXTENTS) {
 +		struct ext3_extent_buf buf;
 +		struct ext3_extents_tree tree;
@@ -2231,8 +2273,10 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +		buf.cur = buf.buffer;
 +		buf.err = 0;
 +		tree.private = &buf;
++		down_write(&EXT3_I(inode)->truncate_sem);
 +		err = ext3_ext_walk_space(&tree, buf.start, 0xffffffff,
 +						ext3_ext_store_extent_cb);
++		up_write(&EXT3_I(inode)->truncate_sem);
 +		if (err == 0)
 +			err = buf.err;
 +	} else if (cmd == EXT3_IOC_GET_TREE_STATS) {
@@ -2240,18 +2284,22 @@ Index: linux-2.4.24/fs/ext3/extents.c
 +		struct ext3_extents_tree tree;
 +
 +		ext3_init_tree_desc(&tree, inode);
++		down_write(&EXT3_I(inode)->truncate_sem);
 +		buf.depth = EXT_DEPTH(&tree);
 +		buf.extents_num = 0;
 +		buf.leaf_num = 0;
 +		tree.private = &buf;
 +		err = ext3_ext_walk_space(&tree, 0, 0xffffffff,
 +						ext3_ext_collect_stats_cb);
++		up_write(&EXT3_I(inode)->truncate_sem);
 +		if (!err)
 +			err = copy_to_user((void *) arg, &buf, sizeof(buf));
 +	} else if (cmd == EXT3_IOC_GET_TREE_DEPTH) {
 +		struct ext3_extents_tree tree;
 +		ext3_init_tree_desc(&tree, inode);
++		down_write(&EXT3_I(inode)->truncate_sem);
 +		err = EXT_DEPTH(&tree);
++		up_write(&EXT3_I(inode)->truncate_sem);
 +	}
 +
 +	return err;
@@ -2479,8 +2527,8 @@ Index: linux-2.4.24/include/linux/ext3_fs.h
 Index: linux-2.4.24/include/linux/ext3_extents.h
 ===================================================================
 --- linux-2.4.24.orig/include/linux/ext3_extents.h	2003-01-30 13:24:37.000000000 +0300
-+++ linux-2.4.24/include/linux/ext3_extents.h	2004-01-26 23:17:19.000000000 +0300
-@@ -0,0 +1,212 @@
++++ linux-2.4.24/include/linux/ext3_extents.h	2004-01-29 01:13:10.000000000 +0300
+@@ -0,0 +1,216 @@
 +/*
 + * Copyright (C) 2003 Alex Tomas <alex@clusterfs.com>
 + *
@@ -2537,7 +2585,7 @@ Index: linux-2.4.24/include/linux/ext3_extents.h
 +#define EXT_STATS_
 +
 +
-+#define EXT3_ALLOC_NEEDED	2	/* block bitmap + group descriptor */
++#define EXT3_ALLOC_NEEDED	3	/* block bitmap + group desc. + sb */
 +
 +/*
 + * ext3_inode has i_block array (total 60 bytes)
@@ -2574,6 +2622,7 @@ Index: linux-2.4.24/include/linux/ext3_extents.h
 +	__u16	e_num;		/* number of valid entries */
 +	__u16	e_max;		/* capacity of store in entries */
 +	__u16	e_depth;	/* has tree real underlaying blocks? */
++	__u32	e_generation;	/* generation of the tree */
 +};
 +
 +#define EXT3_EXT_MAGIC		0xf301
@@ -2634,6 +2683,7 @@ Index: linux-2.4.24/include/linux/ext3_extents.h
 +
 +#define EXT_CONTINUE	0
 +#define EXT_BREAK	1
++#define EXT_REPEAT	2
 +
 +
 +#define EXT_FIRST_EXTENT(__hdr__) \
@@ -2659,6 +2709,8 @@ Index: linux-2.4.24/include/linux/ext3_extents.h
 +	((struct ext3_extent_header *) (bh)->b_data)
 +#define EXT_DEPTH(_t_)	\
 +	(((struct ext3_extent_header *)((_t_)->root))->e_depth)
++#define EXT_GENERATION(_t_)	\
++	(((struct ext3_extent_header *)((_t_)->root))->e_generation)
 +
 +
 +#define EXT_ASSERT(__x__) if (!(__x__)) BUG();
diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.21-suse2.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.21-suse2.patch
index 01f1152b2c51a66506bdad4b62dd450a2869244a..42f39f74783c611487b0fcf1b24ad59d7e5aef01 100644
--- a/lustre/kernel_patches/patches/ext3-extents-2.4.21-suse2.patch
+++ b/lustre/kernel_patches/patches/ext3-extents-2.4.21-suse2.patch
@@ -1,8 +1,8 @@
 Index: linux-2.4.21-suse2/fs/ext3/extents.c
 ===================================================================
 --- linux-2.4.21-suse2.orig/fs/ext3/extents.c	2003-01-30 13:24:37.000000000 +0300
-+++ linux-2.4.21-suse2/fs/ext3/extents.c	2004-01-28 20:15:12.000000000 +0300
-@@ -0,0 +1,2255 @@
++++ linux-2.4.21-suse2/fs/ext3/extents.c	2004-01-29 16:27:55.000000000 +0300
+@@ -0,0 +1,2303 @@
 +/*
 + * Copyright (C) 2003 Alex Tomas <alex@clusterfs.com>
 + *
@@ -88,13 +88,18 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +				struct ext3_extents_tree *tree,
 +				struct ext3_ext_path *path)
 +{
++	int err;
++
 +	if (path->p_bh) {
 +		/* path points to block */
-+		return ext3_journal_get_write_access(handle, path->p_bh);
++		err = ext3_journal_get_write_access(handle, path->p_bh);
++	} else {
++		/* path points to leaf/index in inode body */
++		err = ext3_ext_get_access_for_root(handle, tree);
 +	}
-+
-+	/* path points to leaf/index in inode body */
-+	return ext3_ext_get_access_for_root(handle, tree);
++	if (err)
++		printk("err=%d (%s:%d)\n", err, __FILE__, __LINE__);
++	return err;
 +}
 +
 +/*
@@ -106,13 +111,17 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree,
 +				struct ext3_ext_path *path)
 +{
++	int err;
 +	if (path->p_bh) {
 +		/* path points to block */
-+		return ext3_journal_dirty_metadata(handle, path->p_bh);
++		err =ext3_journal_dirty_metadata(handle, path->p_bh);
++	} else {
++		/* path points to leaf/index in inode body */
++		err = ext3_ext_mark_root_dirty(handle, tree);
 +	}
-+
-+	/* path points to leaf/index in inode body */
-+	return ext3_ext_mark_root_dirty(handle, tree);
++	if (err)
++		printk("err=%d (%s:%d)\n", err, __FILE__, __LINE__);
++	return err;
 +}
 +
 +static int inline
@@ -148,6 +157,13 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +	return newblock;
 +}
 +
++static inline void ext3_ext_tree_changed(struct ext3_extents_tree *tree)
++{
++	struct ext3_extent_header *neh;
++	neh = EXT_ROOT_HDR(tree);
++	neh->e_generation++;
++}
++
 +static inline int ext3_ext_space_block(struct ext3_extents_tree *tree)
 +{
 +	int size;
@@ -614,10 +630,11 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +	path[depth].p_ext++;
 +	while (path[depth].p_ext <=
 +			EXT_MAX_EXTENT(path[depth].p_hdr)) {
-+		ext_debug(tree, "move %d:%d:%d in new leaf\n",
++		ext_debug(tree, "move %d:%d:%d in new leaf %lu\n",
 +				path[depth].p_ext->e_block,
 +				path[depth].p_ext->e_start,
-+				path[depth].p_ext->e_num);
++				path[depth].p_ext->e_num,
++				newblock);
 +		memmove(ex++, path[depth].p_ext++,
 +				sizeof(struct ext3_extent));
 +		neh->e_num++;
@@ -633,10 +650,10 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +
 +	/* correct old leaf */
 +	if (m) {
-+		if ((err = ext3_ext_get_access(handle, tree, path)))
++		if ((err = ext3_ext_get_access(handle, tree, path + depth)))
 +			goto cleanup;
 +		path[depth].p_hdr->e_num -= m;
-+		if ((err = ext3_ext_dirty(handle, tree, path)))
++		if ((err = ext3_ext_dirty(handle, tree, path + depth)))
 +			goto cleanup;
 +		
 +	}
@@ -682,9 +699,9 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +		EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) ==
 +				EXT_LAST_INDEX(path[i].p_hdr));
 +		while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) {
-+			ext_debug(tree, "%d: move %d:%d in new index\n",
++			ext_debug(tree, "%d: move %d:%d in new index %lu\n",
 +					i, path[i].p_idx->e_block,
-+					path[i].p_idx->e_leaf);
++					path[i].p_idx->e_leaf, newblock);
 +			memmove(++fidx, path[i].p_idx++,
 +					sizeof(struct ext3_extent_idx));
 +			neh->e_num++;
@@ -1041,7 +1058,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +			return err;
 +		ex->e_num += newext->e_num;
 +		err = ext3_ext_dirty(handle, tree, path + depth);
-+		return err;
++		ext3_ext_tree_changed(tree);
++		goto out;
 +	}
 +
 +repeat:
@@ -1137,7 +1155,8 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +		ext3_ext_drop_refs(npath);
 +		kfree(npath);
 +	}
-+		
++out:	
++	ext3_ext_tree_changed(tree);
 +	return err;
 +}
 +
@@ -1147,6 +1166,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +	struct ext3_ext_path *path = NULL;
 +	struct ext3_extent *ex, cbex;
 +	unsigned long next, start = 0, end = 0;
++	unsigned long last = block + num;
 +	int depth, exists, err = 0;
 +
 +	EXT_ASSERT(tree);
@@ -1154,11 +1174,13 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +	EXT_ASSERT(tree->inode);
 +	EXT_ASSERT(tree->root);
 +
-+	while (num > 0 && block != 0xfffffffff) {
++	while (block < last && block != 0xfffffffff) {
++		num = last - block;
 +		/* find extent for this block */
 +		path = ext3_ext_find_extent(tree, block, path);
 +		if (IS_ERR(path)) {
 +			err = PTR_ERR(path);
++			path = NULL;
 +			break;
 +		}
 +
@@ -1171,58 +1193,60 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +			/* there is no extent yet, so try to allocate
 +			 * all requested space */
 +			start = block;
-+			end = block + num - 1;
++			end = block + num;
 +		} else if (ex->e_block > block) {
 +			/* need to allocate space before found extent */
 +			start = block;
-+			end = ex->e_block - 1;
-+			if (block + num - 1 < end)
-+				end = block + num - 1;
++			end = ex->e_block;
++			if (block + num < end)
++				end = block + num;
 +		} else if (block >= ex->e_block + ex->e_num) {
 +			/* need to allocate space after found extent */
 +			start = block;
-+			end = block + num - 1;
++			end = block + num;
 +			if (end >= next)
-+				end = next - 1;
++				end = next;
 +		} else if (block >= ex->e_block) {
 +			/* 
 +			 * some part of requested space is covered
 +			 * by found extent
 +			 */
 +			start = block;
-+			end = ex->e_block + ex->e_num - 1;
-+			if (block + num - 1 < end)
-+				end = block + num - 1;
++			end = ex->e_block + ex->e_num;
++			if (block + num < end)
++				end = block + num;
 +			exists = 1;
 +		} else {
 +			BUG();
 +		}
++		EXT_ASSERT(end > start);
 +
 +		if (!exists) {
 +			cbex.e_block = start;
-+			cbex.e_num = end - start + 1;
++			cbex.e_num = end - start;
 +			cbex.e_start = 0;
 +		} else
 +			cbex = *ex;
 +
 +		err = func(tree, path, &cbex, exists);
++		ext3_ext_drop_refs(path);
++
 +		if (err < 0)
 +			break;
-+
-+		if (err == EXT_BREAK) {
++		if (err == EXT_REPEAT)
++			continue;
++		else if (err == EXT_BREAK) {
 +			err = 0;
 +			break;
 +		}
 +
 +		if (EXT_DEPTH(tree) != depth) {
 +			/* depth was changed. we have to realloc path */
-+			ext3_ext_drop_refs(path);
 +			kfree(path);
 +			path = NULL;
 +		}
 +
-+		block += cbex.e_num;
-+		num -= cbex.e_num;
++		block = cbex.e_block + cbex.e_num;
 +	}
 +
 +	if (path) {
@@ -1724,6 +1748,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +			err = ext3_ext_dirty(handle, tree, path);
 +		}
 +	}
++	ext3_ext_tree_changed(tree);
 +
 +	kfree(path);
 +	ext3_journal_stop(handle, inode);
@@ -1772,8 +1797,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +static int ext3_mark_buffer_dirty(handle_t *handle, void *buffer)
 +{
 +	struct inode *inode = buffer;
-+	ext3_mark_inode_dirty(handle, inode);
-+	return 0;
++	return ext3_mark_inode_dirty(handle, inode);
 +}
 +
 +static int ext3_ext_mergable(struct ext3_extent *ex1,
@@ -1914,21 +1938,35 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +	loff_t new_i_size;
 +	handle_t *handle;
 +	unsigned long pblock;
++	unsigned long tgen;
 +
 +	if (exist)
 +		return EXT_CONTINUE;
 +
++	tgen = EXT_GENERATION(tree);
 +	count = ext3_ext_calc_credits_for_insert(tree, path);
++	up_write(&EXT3_I(inode)->truncate_sem);
++
 +	handle = ext3_journal_start(inode, count + EXT3_ALLOC_NEEDED + 1);
-+	if (IS_ERR(handle))
++	if (IS_ERR(handle)) {
++		down_write(&EXT3_I(inode)->truncate_sem);
 +		return PTR_ERR(handle);
++	}
 +
++	if (tgen != EXT_GENERATION(tree)) {
++		/* the tree has changed. so path can be invalid at moment */
++		ext3_journal_stop(handle, inode);
++		down_write(&EXT3_I(inode)->truncate_sem);
++		return EXT_REPEAT;
++	}
++
++	down_write(&EXT3_I(inode)->truncate_sem);
 +	goal = ext3_ext_find_goal(inode, path);
 +	count = newex->e_num;
 +	pblock = ext3_new_blocks(handle, inode, &count, goal, &err);
++	if (!pblock)
++		goto out;
 +	EXT_ASSERT(count <= newex->e_num);
-+	/* FIXME: error handling here */
-+	EXT_ASSERT(err == 0);
 +
 +	/* insert new extent */
 +	newex->e_start = pblock;
@@ -2005,6 +2043,7 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +	path = ext3_ext_find_extent(&tree, iblock, NULL);
 +	if (IS_ERR(path)) {
 +		err = PTR_ERR(path);
++		path = NULL;
 +		goto out2;
 +	}
 +
@@ -2221,6 +2260,9 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +{
 +	int err = 0;
 +
++	if (!(EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL))
++		return -EINVAL;
++
 +	if (cmd == EXT3_IOC_GET_EXTENTS) {
 +		struct ext3_extent_buf buf;
 +		struct ext3_extents_tree tree;
@@ -2232,8 +2274,10 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +		buf.cur = buf.buffer;
 +		buf.err = 0;
 +		tree.private = &buf;
++		down_write(&EXT3_I(inode)->truncate_sem);
 +		err = ext3_ext_walk_space(&tree, buf.start, 0xffffffff,
 +						ext3_ext_store_extent_cb);
++		up_write(&EXT3_I(inode)->truncate_sem);
 +		if (err == 0)
 +			err = buf.err;
 +	} else if (cmd == EXT3_IOC_GET_TREE_STATS) {
@@ -2241,18 +2285,22 @@ Index: linux-2.4.21-suse2/fs/ext3/extents.c
 +		struct ext3_extents_tree tree;
 +
 +		ext3_init_tree_desc(&tree, inode);
++		down_write(&EXT3_I(inode)->truncate_sem);
 +		buf.depth = EXT_DEPTH(&tree);
 +		buf.extents_num = 0;
 +		buf.leaf_num = 0;
 +		tree.private = &buf;
 +		err = ext3_ext_walk_space(&tree, 0, 0xffffffff,
 +						ext3_ext_collect_stats_cb);
++		up_write(&EXT3_I(inode)->truncate_sem);
 +		if (!err)
 +			err = copy_to_user((void *) arg, &buf, sizeof(buf));
 +	} else if (cmd == EXT3_IOC_GET_TREE_DEPTH) {
 +		struct ext3_extents_tree tree;
 +		ext3_init_tree_desc(&tree, inode);
++		down_write(&EXT3_I(inode)->truncate_sem);
 +		err = EXT_DEPTH(&tree);
++		up_write(&EXT3_I(inode)->truncate_sem);
 +	}
 +
 +	return err;
@@ -2488,8 +2536,8 @@ Index: linux-2.4.21-suse2/include/linux/ext3_fs.h
 Index: linux-2.4.21-suse2/include/linux/ext3_extents.h
 ===================================================================
 --- linux-2.4.21-suse2.orig/include/linux/ext3_extents.h	2003-01-30 13:24:37.000000000 +0300
-+++ linux-2.4.21-suse2/include/linux/ext3_extents.h	2004-01-24 20:10:25.000000000 +0300
-@@ -0,0 +1,212 @@
++++ linux-2.4.21-suse2/include/linux/ext3_extents.h	2004-01-29 15:35:26.000000000 +0300
+@@ -0,0 +1,216 @@
 +/*
 + * Copyright (C) 2003 Alex Tomas <alex@clusterfs.com>
 + *
@@ -2546,7 +2594,7 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h
 +#define EXT_STATS_
 +
 +
-+#define EXT3_ALLOC_NEEDED	2	/* block bitmap + group descriptor */
++#define EXT3_ALLOC_NEEDED	3	/* block bitmap + group desc. + sb */
 +
 +/*
 + * ext3_inode has i_block array (total 60 bytes)
@@ -2583,6 +2631,7 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h
 +	__u16	e_num;		/* number of valid entries */
 +	__u16	e_max;		/* capacity of store in entries */
 +	__u16	e_depth;	/* has tree real underlaying blocks? */
++	__u32	e_generation;	/* generation of the tree */
 +};
 +
 +#define EXT3_EXT_MAGIC		0xf301
@@ -2643,6 +2692,7 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h
 +
 +#define EXT_CONTINUE	0
 +#define EXT_BREAK	1
++#define EXT_REPEAT	2
 +
 +
 +#define EXT_FIRST_EXTENT(__hdr__) \
@@ -2668,6 +2718,8 @@ Index: linux-2.4.21-suse2/include/linux/ext3_extents.h
 +	((struct ext3_extent_header *) (bh)->b_data)
 +#define EXT_DEPTH(_t_)	\
 +	(((struct ext3_extent_header *)((_t_)->root))->e_depth)
++#define EXT_GENERATION(_t_)	\
++	(((struct ext3_extent_header *)((_t_)->root))->e_generation)
 +
 +
 +#define EXT_ASSERT(__x__) if (!(__x__)) BUG();