+++ /dev/null
---- linux-2.6.9-full/include/linux/ext3_fs.h 2007-03-23 15:57:00.000000000 +0300
-+++ linux-2.6.9-full/include/linux/ext3_fs.h 2007-02-16 17:16:23.000000000 +0300
-@@ -850,7 +850,7 @@ extern struct inode_operations ext3_fast
-
- /* extents.c */
- extern int ext3_ext_writepage_trans_blocks(struct inode *, int);
--extern int ext3_ext_get_block(handle_t *, struct inode *, long,
-+extern int ext3_ext_get_block(handle_t *, struct inode *, long, int,
- struct buffer_head *, int, int);
- extern void ext3_ext_truncate(struct inode *, struct page *);
- extern void ext3_ext_init(struct super_block *);
-
---- linux-2.6.9-full/fs/ext3/extents.c 2007-03-23 15:57:00.000000000 +0300
-+++ linux-2.6.9-full/fs/ext3/extents.c 2007-02-22 17:45:05.000000000 +0300
-@@ -2031,7 +2168,8 @@ void ext3_init_tree_desc(struct ext3_ext
- }
-
- int ext3_ext_get_block(handle_t *handle, struct inode *inode,
-- long iblock, struct buffer_head *bh_result,
-+ long iblock, int max_blocks,
-+ struct buffer_head *bh_result,
- int create, int extend_disksize)
- {
- struct ext3_ext_path *path = NULL;
-@@ -2039,6 +2177,11 @@ int ext3_ext_get_block(handle_t *handle,
- struct ext3_extent *ex;
- int goal, newblock, err = 0, depth;
- struct ext3_extents_tree tree;
-+ unsigned long next;
-+ int allocated = 0;
-+
-+ /* until we have multiblock allocation */
-+ max_blocks = 1;
-
- clear_buffer_new(bh_result);
- ext3_init_tree_desc(&tree, inode);
-@@ -2058,6 +2201,9 @@ int ext3_ext_get_block(handle_t *handle,
- } else if (goal == EXT3_EXT_CACHE_EXTENT) {
- /* block is already allocated */
- newblock = iblock - newex.ee_block + newex.ee_start;
-+ /* number of remaining blocks in the extent */
-+ EXT_ASSERT(iblock >= newex.ee_block);
-+ allocated = newex.ee_len - (iblock - newex.ee_block);
- goto out;
- } else {
- EXT_ASSERT(0);
-@@ -2085,6 +2231,8 @@ int ext3_ext_get_block(handle_t *handle,
- /* if found exent covers block, simple return it */
- if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) {
- newblock = iblock - ex->ee_block + ex->ee_start;
-+ /* number of remaining blocks in the extent */
-+ allocated = ex->ee_len - (iblock - ex->ee_block);
- ext_debug(&tree, "%d fit into %d:%d -> %d\n",
- (int) iblock, ex->ee_block, ex->ee_len,
- newblock);
-@@ -2105,6 +2253,15 @@ int ext3_ext_get_block(handle_t *handle,
- goto out2;
- }
-
-+ /* find next allocated block so that we know how many
-+ * blocks we can allocate without ovelapping next extent */
-+ EXT_ASSERT(iblock >= ex->ee_block + ex->ee_len);
-+ next = ext3_ext_next_allocated_block(path);
-+ EXT_ASSERT(next > iblock);
-+ allocated = next - iblock;
-+ if (allocated > max_blocks)
-+ allocated = max_blocks;
-+
- /* allocate new block */
- goal = ext3_ext_find_goal(inode, path, iblock);
- newblock = ext3_new_block(handle, inode, goal, &err);
-@@ -2119,8 +2276,11 @@ int ext3_ext_get_block(handle_t *handle,
- newex.ee_start_hi = 0;
- newex.ee_len = 1;
- err = ext3_ext_insert_extent(handle, &tree, path, &newex);
-- if (err)
-+ if (err) {
-+ /* free data blocks we just allocated */
-+ ext3_free_blocks(handle, inode, newex.ee_start, newex.ee_len);
- goto out2;
-+ }
-
- if (extend_disksize && inode->i_size > EXT3_I(inode)->i_disksize)
- EXT3_I(inode)->i_disksize = inode->i_size;
-@@ -2132,8 +2292,11 @@ int ext3_ext_get_block(handle_t *handle,
- ext3_ext_put_in_cache(&tree, newex.ee_block, newex.ee_len,
- newex.ee_start, EXT3_EXT_CACHE_EXTENT);
- out:
-+ if (allocated > max_blocks)
-+ allocated = max_blocks;
- ext3_ext_show_leaf(&tree, path);
- map_bh(bh_result, inode->i_sb, newblock);
-+ bh_result->b_size = (allocated << inode->i_blkbits);
- out2:
- if (path) {
- ext3_ext_drop_refs(path);
---- linux-2.6.9-full/fs/ext3/inode.c 2007-03-23 15:57:00.000000000 +0300
-+++ linux-2.6.9-full/fs/ext3/inode.c 2007-02-16 17:17:03.000000000 +0300
-@@ -798,13 +798,17 @@ changed:
-
- static inline int
- ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block,
-- struct buffer_head *bh, int create, int extend_disksize)
-+ int max_blocks, struct buffer_head *bh, int create,
-+ int extend_disksize)
- {
-+ int ret;
- if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
-- return ext3_ext_get_block(handle, inode, block, bh, create,
-- extend_disksize);
-- return ext3_get_block_handle(handle, inode, block, bh, create,
-+ return ext3_ext_get_block(handle, inode, block, max_blocks,
-+ bh, create, extend_disksize);
-+ ret = ext3_get_block_handle(handle, inode, block, bh, create,
- extend_disksize);
-+ bh->b_size = (1 << inode->i_blkbits);
-+ return ret;
- }
-
- static int ext3_get_block(struct inode *inode, sector_t iblock,
-@@ -817,7 +821,7 @@ static int ext3_get_block(struct inode *
- handle = ext3_journal_current_handle();
- J_ASSERT(handle != 0);
- }
-- ret = ext3_get_block_wrap(handle, inode, iblock,
-+ ret = ext3_get_block_wrap(handle, inode, iblock, 1,
- bh_result, create, 1);
- return ret;
- }
-@@ -862,9 +866,8 @@ ext3_direct_io_get_blocks(struct inode *
-
- get_block:
- if (ret == 0)
-- ret = ext3_get_block_wrap(handle, inode, iblock,
-+ ret = ext3_get_block_wrap(handle, inode, iblock, max_blocks,
- bh_result, create, 0);
-- bh_result->b_size = (1 << inode->i_blkbits);
- return ret;
- }
-
-@@ -882,7 +885,7 @@ struct buffer_head *ext3_getblk(handle_t
- dummy.b_state = 0;
- dummy.b_blocknr = -1000;
- buffer_trace_init(&dummy.b_history);
-- *errp = ext3_get_block_wrap(handle, inode, block, &dummy, create, 1);
-+ *errp = ext3_get_block_wrap(handle, inode, block, 1, &dummy, create, 1);
- if (!*errp && buffer_mapped(&dummy)) {
- struct buffer_head *bh;
- bh = sb_getblk(inode->i_sb, dummy.b_blocknr);