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();