Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-extents-multiblock-directio-2.6.9-rhel4.patch
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
4  
5  /* extents.c */
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 *);
12
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
16  }
17  
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)
23  {
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;
29 +       unsigned long next;
30 +       int allocated = 0;
31 +
32 +       /* until we have multiblock allocation */
33 +       max_blocks = 1;
34  
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);
44                         goto out;
45                 } else {
46                         EXT_ASSERT(0);
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,
55                                   newblock);
56 @@ -2105,6 +2253,15 @@ int ext3_ext_get_block(handle_t *handle,
57                 goto out2;
58         }
59  
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;
68 +
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;
74         newex.ee_len = 1;
75         err = ext3_ext_insert_extent(handle, &tree, path, &newex);
76 -       if (err)
77 +       if (err) {
78 +               /* free data blocks we just allocated */
79 +               ext3_free_blocks(handle, inode, newex.ee_start, newex.ee_len);
80                 goto out2;
81 +       }
82         
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);
88  out:
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);
94  out2:
95         if (path) {
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:
100  
101  static inline int
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)
106  {
107 +       int ret;
108         if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)
109 -               return ext3_ext_get_block(handle, inode, block, bh, create,
110 -                                         extend_disksize);
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,
115                                      extend_disksize);
116 +       bh->b_size = (1 << inode->i_blkbits);
117 +       return ret;
118  }
119  
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);
124         }
125 -       ret = ext3_get_block_wrap(handle, inode, iblock,
126 +       ret = ext3_get_block_wrap(handle, inode, iblock, 1,
127                                   bh_result, create, 1);
128         return ret;
129  }
130 @@ -862,9 +866,8 @@ ext3_direct_io_get_blocks(struct inode *
131  
132  get_block:
133         if (ret == 0)
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);
138         return ret;
139  }
140  
141 @@ -882,7 +885,7 @@ struct buffer_head *ext3_getblk(handle_t
142         dummy.b_state = 0;
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);