1 --- linux-2.6.9-full/include/linux/ext3_fs.h 2007-03-23 15:57:00.000000000 +0300
2 +++ linux-2.6.9-full/include/linux/ext3_fs.h 2007-02-16 17:16:23.000000000 +0300
3 @@ -850,7 +850,7 @@ extern struct inode_operations ext3_fast
6 extern int ext3_ext_writepage_trans_blocks(struct inode *, int);
7 -extern int ext3_ext_get_block(handle_t *, struct inode *, long,
8 +extern int ext3_ext_get_block(handle_t *, struct inode *, long, int,
9 struct buffer_head *, int, int);
10 extern void ext3_ext_truncate(struct inode *, struct page *);
11 extern void ext3_ext_init(struct super_block *);
13 --- linux-2.6.9-full/fs/ext3/extents.c 2007-03-23 15:57:00.000000000 +0300
14 +++ linux-2.6.9-full/fs/ext3/extents.c 2007-02-22 17:45:05.000000000 +0300
15 @@ -2031,7 +2168,8 @@ void ext3_init_tree_desc(struct ext3_ext
18 int ext3_ext_get_block(handle_t *handle, struct inode *inode,
19 - long iblock, struct buffer_head *bh_result,
20 + long iblock, int max_blocks,
21 + struct buffer_head *bh_result,
22 int create, int extend_disksize)
24 struct ext3_ext_path *path = NULL;
25 @@ -2039,6 +2177,11 @@ int ext3_ext_get_block(handle_t *handle,
26 struct ext3_extent *ex;
27 int goal, newblock, err = 0, depth;
28 struct ext3_extents_tree tree;
32 + /* until we have multiblock allocation */
35 clear_buffer_new(bh_result);
36 ext3_init_tree_desc(&tree, inode);
37 @@ -2058,6 +2201,9 @@ int ext3_ext_get_block(handle_t *handle,
38 } else if (goal == EXT3_EXT_CACHE_EXTENT) {
39 /* block is already allocated */
40 newblock = iblock - newex.ee_block + newex.ee_start;
41 + /* number of remaining blocks in the extent */
42 + EXT_ASSERT(iblock >= newex.ee_block);
43 + allocated = newex.ee_len - (iblock - newex.ee_block);
47 @@ -2085,6 +2231,8 @@ int ext3_ext_get_block(handle_t *handle,
48 /* if found exent covers block, simple return it */
49 if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) {
50 newblock = iblock - ex->ee_block + ex->ee_start;
51 + /* number of remaining blocks in the extent */
52 + allocated = ex->ee_len - (iblock - ex->ee_block);
53 ext_debug(&tree, "%d fit into %d:%d -> %d\n",
54 (int) iblock, ex->ee_block, ex->ee_len,
56 @@ -2105,6 +2253,15 @@ int ext3_ext_get_block(handle_t *handle,
60 + /* find next allocated block so that we know how many
61 + * blocks we can allocate without ovelapping next extent */
62 + EXT_ASSERT(iblock >= ex->ee_block + ex->ee_len);
63 + next = ext3_ext_next_allocated_block(path);
64 + EXT_ASSERT(next > iblock);
65 + allocated = next - iblock;
66 + if (allocated > max_blocks)
67 + allocated = max_blocks;
69 /* allocate new block */
70 goal = ext3_ext_find_goal(inode, path, iblock);
71 newblock = ext3_new_block(handle, inode, goal, &err);
72 @@ -2119,8 +2276,11 @@ int ext3_ext_get_block(handle_t *handle,
73 newex.ee_start_hi = 0;
75 err = ext3_ext_insert_extent(handle, &tree, path, &newex);
78 + /* free data blocks we just allocated */
79 + ext3_free_blocks(handle, inode, newex.ee_start, newex.ee_len);
83 if (extend_disksize && inode->i_size > EXT3_I(inode)->i_disksize)
84 EXT3_I(inode)->i_disksize = inode->i_size;
85 @@ -2132,8 +2292,11 @@ int ext3_ext_get_block(handle_t *handle,
86 ext3_ext_put_in_cache(&tree, newex.ee_block, newex.ee_len,
87 newex.ee_start, EXT3_EXT_CACHE_EXTENT);
89 + if (allocated > max_blocks)
90 + allocated = max_blocks;
91 ext3_ext_show_leaf(&tree, path);
92 map_bh(bh_result, inode->i_sb, newblock);
93 + bh_result->b_size = (allocated << inode->i_blkbits);
96 ext3_ext_drop_refs(path);
97 --- linux-2.6.9-full/fs/ext3/inode.c 2007-03-23 15:57:00.000000000 +0300
98 +++ linux-2.6.9-full/fs/ext3/inode.c 2007-02-16 17:17:03.000000000 +0300
99 @@ -798,13 +798,17 @@ changed:
102 ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block,
103 - struct buffer_head *bh, int create, int extend_disksize)
104 + int max_blocks, struct buffer_head *bh, int create,
105 + int extend_disksize)
108 if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
109 - return ext3_ext_get_block(handle, inode, block, bh, create,
111 - return ext3_get_block_handle(handle, inode, block, bh, create,
112 + return ext3_ext_get_block(handle, inode, block, max_blocks,
113 + bh, create, extend_disksize);
114 + ret = ext3_get_block_handle(handle, inode, block, bh, create,
116 + bh->b_size = (1 << inode->i_blkbits);
120 static int ext3_get_block(struct inode *inode, sector_t iblock,
121 @@ -817,7 +821,7 @@ static int ext3_get_block(struct inode *
122 handle = ext3_journal_current_handle();
123 J_ASSERT(handle != 0);
125 - ret = ext3_get_block_wrap(handle, inode, iblock,
126 + ret = ext3_get_block_wrap(handle, inode, iblock, 1,
127 bh_result, create, 1);
130 @@ -862,9 +866,8 @@ ext3_direct_io_get_blocks(struct inode *
134 - ret = ext3_get_block_wrap(handle, inode, iblock,
135 + ret = ext3_get_block_wrap(handle, inode, iblock, max_blocks,
136 bh_result, create, 0);
137 - bh_result->b_size = (1 << inode->i_blkbits);
141 @@ -882,7 +885,7 @@ struct buffer_head *ext3_getblk(handle_t
143 dummy.b_blocknr = -1000;
144 buffer_trace_init(&dummy.b_history);
145 - *errp = ext3_get_block_wrap(handle, inode, block, &dummy, create, 1);
146 + *errp = ext3_get_block_wrap(handle, inode, block, 1, &dummy, create, 1);
147 if (!*errp && buffer_mapped(&dummy)) {
148 struct buffer_head *bh;
149 bh = sb_getblk(inode->i_sb, dummy.b_blocknr);