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-29 16:27:55.000000000 +0300
-@@ -0,0 +1,2303 @@
++++ linux-2.4.21-suse2/fs/ext3/extents.c 2004-02-06 10:19:27.000000000 +0300
+@@ -0,0 +1,2348 @@
+/*
+ * Copyright (C) 2003 Alex Tomas <alex@clusterfs.com>
+ *
+ /* path points to leaf/index in inode body */
+ err = ext3_ext_get_access_for_root(handle, tree);
+ }
-+ if (err)
-+ printk("err=%d (%s:%d)\n", err, __FILE__, __LINE__);
+ return err;
+}
+
+ /* path points to leaf/index in inode body */
+ err = ext3_ext_mark_root_dirty(handle, tree);
+ }
-+ if (err)
-+ printk("err=%d (%s:%d)\n", err, __FILE__, __LINE__);
+ return err;
+}
+
+ EXT_ASSERT(tree->root);
+
+ eh = EXT_ROOT_HDR(tree);
++ EXT_ASSERT(eh);
+ i = depth = EXT_DEPTH(tree);
+ EXT_ASSERT(eh->e_max);
+ EXT_ASSERT(eh->e_magic == EXT3_EXT_MAGIC);
+
+ depth = EXT_DEPTH(tree);
+ ex = path[depth].p_ext;
++ EXT_ASSERT(path[depth].p_hdr);
+
+ /* try to insert block into found extent and return */
+ if (ex && ext3_can_extents_be_merged(tree, ex, newext)) {
+ if ((err = ext3_ext_get_access(handle, tree, path + depth)))
+ return err;
+ ex->e_num += newext->e_num;
-+ err = ext3_ext_dirty(handle, tree, path + depth);
-+ ext3_ext_tree_changed(tree);
-+ goto out;
++ eh = path[depth].p_hdr;
++ nearex = ex;
++ goto merge;
+ }
+
+repeat:
+ nearex->e_start = newext->e_start;
+ nearex->e_num = newext->e_num;
+
++merge:
++ /* try to merge extents to the right */
++ while (nearex < EXT_LAST_EXTENT(eh)) {
++ if (!ext3_can_extents_be_merged(tree, nearex, nearex + 1))
++ break;
++ /* merge with next extent! */
++ nearex->e_num += nearex[1].e_num;
++ if (nearex + 1 < EXT_LAST_EXTENT(eh)) {
++ len = (EXT_LAST_EXTENT(eh) - nearex - 1)
++ * sizeof(struct ext3_extent);
++ memmove(nearex + 1, nearex + 2, len);
++ }
++ eh->e_num--;
++ EXT_ASSERT(eh->e_num > 0);
++ }
++
++ /* try to merge extents to the left */
++
+ /* time to correct all indexes above */
+ err = ext3_ext_correct_indexes(handle, tree, path);
+ if (err)
+ ext3_ext_drop_refs(npath);
+ kfree(npath);
+ }
-+out:
+ ext3_ext_tree_changed(tree);
+ return err;
+}
+ }
+
+ depth = EXT_DEPTH(tree);
++ EXT_ASSERT(path[depth].p_hdr);
+ ex = path[depth].p_ext;
+ next = ext3_ext_next_allocated_block(path);
+
+ } else
+ cbex = *ex;
+
++ EXT_ASSERT(path[depth].p_hdr);
+ err = func(tree, path, &cbex, exists);
+ ext3_ext_drop_refs(path);
+
+ ext_debug(tree, "index is empty, remove it, free block %d\n",
+ path->p_idx->e_leaf);
+ bh = sb_get_hash_table(tree->inode->i_sb, path->p_idx->e_leaf);
-+ ext3_forget(handle, 0, tree->inode, bh, path->p_idx->e_leaf);
++ ext3_forget(handle, 1, tree->inode, bh, path->p_idx->e_leaf);
+ ext3_free_blocks(handle, tree->inode, path->p_idx->e_leaf, 1);
+ return err;
+}
+{
+ int needed = ext3_remove_blocks_credits(tree, ex, from, to);
+ handle_t *handle = ext3_journal_start(tree->inode, needed);
++ struct buffer_head *bh;
++ int i;
+
+ if (IS_ERR(handle))
+ return PTR_ERR(handle);
+ start = ex->e_start + ex->e_num - num;
+ ext_debug(tree, "free last %lu blocks starting %lu\n",
+ num, start);
++ for (i = 0; i < num; i++) {
++ bh = sb_get_hash_table(tree->inode->i_sb, start + i);
++ ext3_forget(handle, 0, tree->inode, bh, start + i);
++ }
+ ext3_free_blocks(handle, tree->inode, start, num);
+ } else if (from == ex->e_block && to <= ex->e_block + ex->e_num - 1) {
+ printk("strange request: removal %lu-%lu from %u:%u\n",
+ return 0;
+}
+
-+static int ext3_ext_find_goal(struct inode *inode,
-+ struct ext3_ext_path *path)
++static int ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path,
++ unsigned long block)
+{
+ struct ext3_inode_info *ei = EXT3_I(inode);
+ unsigned long bg_start;
+ int depth;
+
+ if (path) {
++ struct ext3_extent *ex;
+ depth = path->p_depth;
-+ /* try to find previous block */
-+ if (path[depth].p_ext)
-+ return path[depth].p_ext->e_start +
-+ path[depth].p_ext->e_num;
+
++ /* try to predict block placement */
++ if ((ex = path[depth].p_ext))
++ return ex->e_start + (block - ex->e_block);
++
+ /* it looks index is empty
+ * try to find starting from index itself */
+ if (path[depth].p_bh)
+ le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block);
+ colour = (current->pid % 16) *
+ (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16);
-+ return bg_start + colour;
++ return bg_start + colour + block;
+}
+
+static int ext3_new_block_cb(handle_t *handle, struct ext3_extents_tree *tree,
+ if (ex->e_num == 0) {
+ ex->e_num = 1;
+ /* allocate new block for the extent */
-+ goal = ext3_ext_find_goal(inode, path);
++ goal = ext3_ext_find_goal(inode, path, ex->e_block);
+ ex->e_start = ext3_new_block(handle, inode, goal, 0, 0, err);
+ if (ex->e_start == 0) {
+ /* error occured: restore old extent */
+ struct ext3_extent *newex, int exist)
+{
+ struct inode *inode = tree->inode;
++ struct buffer_head *bh;
+ int count, err, goal;
-+ loff_t new_i_size;
-+ handle_t *handle;
+ unsigned long pblock;
+ unsigned long tgen;
++ loff_t new_i_size;
++ handle_t *handle;
++ int i;
+
+ if (exist)
+ return EXT_CONTINUE;
+ }
+
+ down_write(&EXT3_I(inode)->truncate_sem);
-+ goal = ext3_ext_find_goal(inode, path);
++ goal = ext3_ext_find_goal(inode, path, newex->e_block);
+ count = newex->e_num;
+ pblock = ext3_new_blocks(handle, inode, &count, goal, &err);
+ if (!pblock)
+ if (err)
+ goto out;
+
++ /* block have been allocated for data, so time to drop dirty
++ * in correspondend buffer_heads to prevent corruptions */
++ for (i = 0; i < newex->e_num; i++) {
++ bh = sb_get_hash_table(inode->i_sb, newex->e_start + i);
++ if (bh) {
++ mark_buffer_clean(bh);
++ wait_on_buffer(bh);
++ clear_bit(BH_Req, &bh->b_state);
++ __brelse(bh);
++ }
++ }
+
+ /* correct on-disk inode size */
+ if (newex->e_num > 0) {
+ }
+
+ /* allocate new block */
-+ goal = ext3_ext_find_goal(inode, path);
++ goal = ext3_ext_find_goal(inode, path, iblock);
+ newblock = ext3_new_block(handle, inode, goal, 0, 0, &err);
+ if (!newblock)
+ goto out2;
+ return err;
+}
+
++EXPORT_SYMBOL(ext3_init_tree_desc);
++EXPORT_SYMBOL(ext3_mark_inode_dirty);
++EXPORT_SYMBOL(ext3_ext_invalidate_cache);
++EXPORT_SYMBOL(ext3_ext_insert_extent);
++EXPORT_SYMBOL(ext3_ext_walk_space);
++EXPORT_SYMBOL(ext3_ext_find_goal);
++EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert);
++
Index: linux-2.4.21-suse2/fs/ext3/ialloc.c
===================================================================
---- linux-2.4.21-suse2.orig/fs/ext3/ialloc.c 2004-01-23 19:04:17.000000000 +0300
-+++ linux-2.4.21-suse2/fs/ext3/ialloc.c 2004-01-24 20:10:25.000000000 +0300
+--- linux-2.4.21-suse2.orig/fs/ext3/ialloc.c 2004-02-05 20:42:40.000000000 +0300
++++ linux-2.4.21-suse2/fs/ext3/ialloc.c 2004-02-05 20:42:40.000000000 +0300
@@ -592,6 +592,10 @@
iloc.bh = NULL;
goto fail;
Index: linux-2.4.21-suse2/fs/ext3/inode.c
===================================================================
---- linux-2.4.21-suse2.orig/fs/ext3/inode.c 2004-01-23 19:04:17.000000000 +0300
-+++ linux-2.4.21-suse2/fs/ext3/inode.c 2004-01-24 20:10:25.000000000 +0300
+--- linux-2.4.21-suse2.orig/fs/ext3/inode.c 2004-02-05 20:42:40.000000000 +0300
++++ linux-2.4.21-suse2/fs/ext3/inode.c 2004-02-05 20:42:40.000000000 +0300
@@ -853,6 +853,18 @@
goto reread;
}
"allocating block %ld\n", rc, iblock);
Index: linux-2.4.21-suse2/fs/ext3/Makefile
===================================================================
---- linux-2.4.21-suse2.orig/fs/ext3/Makefile 2004-01-13 17:45:20.000000000 +0300
-+++ linux-2.4.21-suse2/fs/ext3/Makefile 2004-01-24 20:10:25.000000000 +0300
-@@ -12,7 +12,8 @@
+--- linux-2.4.21-suse2.orig/fs/ext3/Makefile 2004-02-05 20:42:39.000000000 +0300
++++ linux-2.4.21-suse2/fs/ext3/Makefile 2004-02-05 20:43:47.000000000 +0300
+@@ -12,7 +12,9 @@
export-objs := ext3-exports.o
obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
- ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o
+ ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \
+ extents.o
++export-objs += extents.o
obj-m := $(O_TARGET)
export-objs += xattr.o
Index: linux-2.4.21-suse2/fs/ext3/super.c
===================================================================
---- linux-2.4.21-suse2.orig/fs/ext3/super.c 2004-01-23 19:04:17.000000000 +0300
-+++ linux-2.4.21-suse2/fs/ext3/super.c 2004-01-24 20:10:25.000000000 +0300
+--- linux-2.4.21-suse2.orig/fs/ext3/super.c 2004-02-05 20:42:40.000000000 +0300
++++ linux-2.4.21-suse2/fs/ext3/super.c 2004-02-05 20:42:40.000000000 +0300
@@ -624,6 +624,7 @@
int i;
failed_mount3:
Index: linux-2.4.21-suse2/fs/ext3/ioctl.c
===================================================================
---- linux-2.4.21-suse2.orig/fs/ext3/ioctl.c 2004-01-13 17:45:18.000000000 +0300
-+++ linux-2.4.21-suse2/fs/ext3/ioctl.c 2004-01-24 20:10:25.000000000 +0300
+--- linux-2.4.21-suse2.orig/fs/ext3/ioctl.c 2004-02-05 20:42:39.000000000 +0300
++++ linux-2.4.21-suse2/fs/ext3/ioctl.c 2004-02-05 20:42:40.000000000 +0300
@@ -174,6 +174,10 @@
return ret;
}
}
Index: linux-2.4.21-suse2/include/linux/ext3_fs.h
===================================================================
---- linux-2.4.21-suse2.orig/include/linux/ext3_fs.h 2004-01-23 19:04:17.000000000 +0300
-+++ linux-2.4.21-suse2/include/linux/ext3_fs.h 2004-01-24 20:10:25.000000000 +0300
+--- linux-2.4.21-suse2.orig/include/linux/ext3_fs.h 2004-02-05 20:42:40.000000000 +0300
++++ linux-2.4.21-suse2/include/linux/ext3_fs.h 2004-02-05 20:42:40.000000000 +0300
@@ -184,6 +184,7 @@
#define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */
#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */
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-29 15:35:26.000000000 +0300
++++ linux-2.4.21-suse2/include/linux/ext3_extents.h 2004-02-05 20:42:40.000000000 +0300
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2003 Alex Tomas <alex@clusterfs.com>
+
Index: linux-2.4.21-suse2/include/linux/ext3_fs_i.h
===================================================================
---- linux-2.4.21-suse2.orig/include/linux/ext3_fs_i.h 2004-01-23 19:04:17.000000000 +0300
-+++ linux-2.4.21-suse2/include/linux/ext3_fs_i.h 2004-01-24 20:10:25.000000000 +0300
+--- linux-2.4.21-suse2.orig/include/linux/ext3_fs_i.h 2004-02-05 20:42:40.000000000 +0300
++++ linux-2.4.21-suse2/include/linux/ext3_fs_i.h 2004-02-05 20:47:04.000000000 +0300
@@ -90,6 +90,8 @@
* by other means, so we have truncate_sem.
*/