Drop redundant patch arm-proc-v7.diff
[kernel-power] / kernel-power-2.6.28 / debian / patches / ext4-data-corruption.diff
1 diff -uprN linux-2.6.28.orig/Documentation/filesystems/ext4.txt linux-2.6.28/Documentation/filesystems/ext4.txt\r
2 --- linux-2.6.28.orig/Documentation/filesystems/ext4.txt        2009-05-02 20:54:43.000000000 +0200\r
3 +++ linux-2.6.28/Documentation/filesystems/ext4.txt     2009-05-23 16:05:41.000000000 +0200\r
4 @@ -76,7 +76,7 @@ Note: More extensive information for get\r
5  * extent format more robust in face of on-disk corruption due to magics,\r
6  * internal redunancy in tree\r
7  * improved file allocation (multi-block alloc)\r
8 -* fix 32000 subdirectory limit\r
9 +* lift 32000 subdirectory limit imposed by i_links_count[1]\r
10  * nsec timestamps for mtime, atime, ctime, create time\r
11  * inode version field on disk (NFSv4, Lustre)\r
12  * reduced e2fsck time via uninit_bg feature\r
13 @@ -91,6 +91,9 @@ Note: More extensive information for get\r
14  * efficent new ordered mode in JBD2 and ext4(avoid using buffer head to force\r
15    the ordering)\r
16  \r
17 +[1] Filesystems with a block size of 1k may see a limit imposed by the\r
18 +directory hash tree having a maximum depth of two.\r
19 +\r
20  2.2 Candidate features for future inclusion\r
21  \r
22  * Online defrag (patches available but not well tested)\r
23 diff -uprN linux-2.6.28.orig/fs/ext4/balloc.c linux-2.6.28/fs/ext4/balloc.c\r
24 --- linux-2.6.28.orig/fs/ext4/balloc.c  2009-05-02 20:54:43.000000000 +0200\r
25 +++ linux-2.6.28/fs/ext4/balloc.c       2009-05-23 16:05:41.000000000 +0200\r
26 @@ -608,7 +608,9 @@ int ext4_claim_free_blocks(struct ext4_s\r
27   */\r
28  int ext4_should_retry_alloc(struct super_block *sb, int *retries)\r
29  {\r
30 -       if (!ext4_has_free_blocks(EXT4_SB(sb), 1) || (*retries)++ > 3)\r
31 +       if (!ext4_has_free_blocks(EXT4_SB(sb), 1) ||\r
32 +           (*retries)++ > 3 ||\r
33 +           !EXT4_SB(sb)->s_journal)\r
34                 return 0;\r
35  \r
36         jbd_debug(1, "%s: retrying operation after ENOSPC\n", sb->s_id);\r
37 diff -uprN linux-2.6.28.orig/fs/ext4/ext4.h linux-2.6.28/fs/ext4/ext4.h\r
38 --- linux-2.6.28.orig/fs/ext4/ext4.h    2009-05-02 20:54:43.000000000 +0200\r
39 +++ linux-2.6.28/fs/ext4/ext4.h 2009-05-23 16:05:41.000000000 +0200\r
40 @@ -248,6 +248,30 @@ struct flex_groups {\r
41  #define EXT4_FL_USER_VISIBLE           0x000BDFFF /* User visible flags */\r
42  #define EXT4_FL_USER_MODIFIABLE                0x000B80FF /* User modifiable flags */\r
43  \r
44 +/* Flags that should be inherited by new inodes from their parent. */\r
45 +#define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\\r
46 +                          EXT4_SYNC_FL | EXT4_IMMUTABLE_FL | EXT4_APPEND_FL |\\r
47 +                          EXT4_NODUMP_FL | EXT4_NOATIME_FL |\\r
48 +                          EXT4_NOCOMPR_FL | EXT4_JOURNAL_DATA_FL |\\r
49 +                          EXT4_NOTAIL_FL | EXT4_DIRSYNC_FL)\r
50 +\r
51 +/* Flags that are appropriate for regular files (all but dir-specific ones). */\r
52 +#define EXT4_REG_FLMASK (~(EXT4_DIRSYNC_FL | EXT4_TOPDIR_FL))\r
53 +\r
54 +/* Flags that are appropriate for non-directories/regular files. */\r
55 +#define EXT4_OTHER_FLMASK (EXT4_NODUMP_FL | EXT4_NOATIME_FL)\r
56 +\r
57 +/* Mask out flags that are inappropriate for the given type of inode. */\r
58 +static inline __u32 ext4_mask_flags(umode_t mode, __u32 flags)\r
59 +{\r
60 +       if (S_ISDIR(mode))\r
61 +               return flags;\r
62 +       else if (S_ISREG(mode))\r
63 +               return flags & EXT4_REG_FLMASK;\r
64 +       else\r
65 +               return flags & EXT4_OTHER_FLMASK;\r
66 +}\r
67 +\r
68  /*\r
69   * Inode dynamic state flags\r
70   */\r
71 @@ -529,7 +556,7 @@ do {                                                                               \\r
72  #define EXT4_MOUNT_NO_UID32            0x02000  /* Disable 32-bit UIDs */\r
73  #define EXT4_MOUNT_XATTR_USER          0x04000 /* Extended user attributes */\r
74  #define EXT4_MOUNT_POSIX_ACL           0x08000 /* POSIX Access Control Lists */\r
75 -#define EXT4_MOUNT_RESERVATION         0x10000 /* Preallocation */\r
76 +#define EXT4_MOUNT_NO_AUTO_DA_ALLOC    0x10000 /* No auto delalloc mapping */\r
77  #define EXT4_MOUNT_BARRIER             0x20000 /* Use block barriers */\r
78  #define EXT4_MOUNT_NOBH                        0x40000 /* No bufferheads */\r
79  #define EXT4_MOUNT_QUOTA               0x80000 /* Some quota option set */\r
80 diff -uprN linux-2.6.28.orig/fs/ext4/extents.c linux-2.6.28/fs/ext4/extents.c\r
81 --- linux-2.6.28.orig/fs/ext4/extents.c 2009-05-02 20:54:43.000000000 +0200\r
82 +++ linux-2.6.28/fs/ext4/extents.c      2009-05-23 16:05:41.000000000 +0200\r
83 @@ -1120,7 +1120,8 @@ ext4_ext_search_right(struct inode *inod\r
84         struct ext4_extent_idx *ix;\r
85         struct ext4_extent *ex;\r
86         ext4_fsblk_t block;\r
87 -       int depth, ee_len;\r
88 +       int depth;      /* Note, NOT eh_depth; depth from top of tree */\r
89 +       int ee_len;\r
90  \r
91         BUG_ON(path == NULL);\r
92         depth = path->p_depth;\r
93 @@ -1179,7 +1180,8 @@ ext4_ext_search_right(struct inode *inod\r
94                 if (bh == NULL)\r
95                         return -EIO;\r
96                 eh = ext_block_hdr(bh);\r
97 -               if (ext4_ext_check_header(inode, eh, depth)) {\r
98 +               /* subtract from p_depth to get proper eh_depth */\r
99 +               if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) {\r
100                         put_bh(bh);\r
101                         return -EIO;\r
102                 }\r
103 @@ -1740,11 +1742,13 @@ ext4_ext_put_in_cache(struct inode *inod\r
104  {\r
105         struct ext4_ext_cache *cex;\r
106         BUG_ON(len == 0);\r
107 +       spin_lock(&EXT4_I(inode)->i_block_reservation_lock);\r
108         cex = &EXT4_I(inode)->i_cached_extent;\r
109         cex->ec_type = type;\r
110         cex->ec_block = block;\r
111         cex->ec_len = len;\r
112         cex->ec_start = start;\r
113 +       spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);\r
114  }\r
115  \r
116  /*\r
117 @@ -1801,12 +1805,17 @@ ext4_ext_in_cache(struct inode *inode, e\r
118                         struct ext4_extent *ex)\r
119  {\r
120         struct ext4_ext_cache *cex;\r
121 +       int ret = EXT4_EXT_CACHE_NO;\r
122  \r
123 +       /* \r
124 +        * We borrow i_block_reservation_lock to protect i_cached_extent\r
125 +        */\r
126 +       spin_lock(&EXT4_I(inode)->i_block_reservation_lock);\r
127         cex = &EXT4_I(inode)->i_cached_extent;\r
128  \r
129         /* has cache valid data? */\r
130         if (cex->ec_type == EXT4_EXT_CACHE_NO)\r
131 -               return EXT4_EXT_CACHE_NO;\r
132 +               goto errout;\r
133  \r
134         BUG_ON(cex->ec_type != EXT4_EXT_CACHE_GAP &&\r
135                         cex->ec_type != EXT4_EXT_CACHE_EXTENT);\r
136 @@ -1817,11 +1826,11 @@ ext4_ext_in_cache(struct inode *inode, e\r
137                 ext_debug("%u cached by %u:%u:%llu\n",\r
138                                 block,\r
139                                 cex->ec_block, cex->ec_len, cex->ec_start);\r
140 -               return cex->ec_type;\r
141 +               ret = cex->ec_type;\r
142         }\r
143 -\r
144 -       /* not in cache */\r
145 -       return EXT4_EXT_CACHE_NO;\r
146 +errout:\r
147 +       spin_unlock(&EXT4_I(inode)->i_block_reservation_lock);\r
148 +       return ret;\r
149  }\r
150  \r
151  /*\r
152 @@ -2777,6 +2786,8 @@ int ext4_ext_get_blocks(handle_t *handle\r
153                                 if (allocated > max_blocks)\r
154                                         allocated = max_blocks;\r
155                                 set_buffer_unwritten(bh_result);\r
156 +                               bh_result->b_bdev = inode->i_sb->s_bdev;\r
157 +                               bh_result->b_blocknr = newblock;\r
158                                 goto out2;\r
159                         }\r
160  \r
161 diff -uprN linux-2.6.28.orig/fs/ext4/ialloc.c linux-2.6.28/fs/ext4/ialloc.c\r
162 --- linux-2.6.28.orig/fs/ext4/ialloc.c  2009-05-02 20:54:43.000000000 +0200\r
163 +++ linux-2.6.28/fs/ext4/ialloc.c       2009-05-23 16:05:41.000000000 +0200\r
164 @@ -188,7 +188,7 @@ void ext4_free_inode(handle_t *handle, s\r
165         struct ext4_group_desc *gdp;\r
166         struct ext4_super_block *es;\r
167         struct ext4_sb_info *sbi;\r
168 -       int fatal = 0, err;\r
169 +       int fatal = 0, err, cleared;\r
170         ext4_group_t flex_group;\r
171  \r
172         if (atomic_read(&inode->i_count) > 1) {\r
173 @@ -243,8 +243,10 @@ void ext4_free_inode(handle_t *handle, s\r
174                 goto error_return;\r
175  \r
176         /* Ok, now we can actually update the inode bitmaps.. */\r
177 -       if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group),\r
178 -                                       bit, bitmap_bh->b_data))\r
179 +       spin_lock(sb_bgl_lock(sbi, block_group));\r
180 +       cleared = ext4_clear_bit(bit, bitmap_bh->b_data);\r
181 +       spin_unlock(sb_bgl_lock(sbi, block_group));\r
182 +       if (!cleared)\r
183                 ext4_error(sb, "ext4_free_inode",\r
184                            "bit already cleared for inode %lu", ino);\r
185         else {\r
186 @@ -686,6 +688,7 @@ struct inode *ext4_new_inode(handle_t *h\r
187         struct inode *ret;\r
188         ext4_group_t i;\r
189         int free = 0;\r
190 +       static int once = 1;\r
191         ext4_group_t flex_group;\r
192  \r
193         /* Cannot create files in a deleted directory */\r
194 @@ -705,10 +708,12 @@ struct inode *ext4_new_inode(handle_t *h\r
195                 ret2 = find_group_flex(sb, dir, &group);\r
196                 if (ret2 == -1) {\r
197                         ret2 = find_group_other(sb, dir, &group);\r
198 -                       if (ret2 == 0 && printk_ratelimit())\r
199 +                       if (ret2 == 0 && once) {\r
200 +                               once = 0;\r
201                                 printk(KERN_NOTICE "ext4: find_group_flex "\r
202                                        "failed, fallback succeeded dir %lu\n",\r
203                                        dir->i_ino);\r
204 +                       }\r
205                 }\r
206                 goto got_group;\r
207         }\r
208 @@ -862,16 +867,12 @@ got:\r
209         ei->i_disksize = 0;\r
210  \r
211         /*\r
212 -        * Don't inherit extent flag from directory. We set extent flag on\r
213 -        * newly created directory and file only if -o extent mount option is\r
214 -        * specified\r
215 +        * Don't inherit extent flag from directory, amongst others. We set\r
216 +        * extent flag on newly created directory and file only if -o extent\r
217 +        * mount option is specified\r
218          */\r
219 -       ei->i_flags = EXT4_I(dir)->i_flags & ~(EXT4_INDEX_FL|EXT4_EXTENTS_FL);\r
220 -       if (S_ISLNK(mode))\r
221 -               ei->i_flags &= ~(EXT4_IMMUTABLE_FL|EXT4_APPEND_FL);\r
222 -       /* dirsync only applies to directories */\r
223 -       if (!S_ISDIR(mode))\r
224 -               ei->i_flags &= ~EXT4_DIRSYNC_FL;\r
225 +       ei->i_flags =\r
226 +               ext4_mask_flags(mode, EXT4_I(dir)->i_flags & EXT4_FL_INHERITED);\r
227         ei->i_file_acl = 0;\r
228         ei->i_dtime = 0;\r
229         ei->i_block_group = group;\r
230 diff -uprN linux-2.6.28.orig/fs/ext4/inode.c linux-2.6.28/fs/ext4/inode.c\r
231 --- linux-2.6.28.orig/fs/ext4/inode.c   2009-05-02 20:54:43.000000000 +0200\r
232 +++ linux-2.6.28/fs/ext4/inode.c        2009-05-23 16:05:41.000000000 +0200\r
233 @@ -1052,6 +1059,7 @@ int ext4_get_blocks_wrap(handle_t *handl\r
234         int retval;\r
235  \r
236         clear_buffer_mapped(bh);\r
237 +       clear_buffer_unwritten(bh);\r
238  \r
239         /*\r
240          * Try to see if we can get  the block without requesting\r
241 @@ -1082,6 +1090,18 @@ int ext4_get_blocks_wrap(handle_t *handl\r
242                 return retval;\r
243  \r
244         /*\r
245 +        * When we call get_blocks without the create flag, the\r
246 +        * BH_Unwritten flag could have gotten set if the blocks\r
247 +        * requested were part of a uninitialized extent.  We need to\r
248 +        * clear this flag now that we are committed to convert all or\r
249 +        * part of the uninitialized extent to be an initialized\r
250 +        * extent.  This is because we need to avoid the combination\r
251 +        * of BH_Unwritten and BH_Mapped flags being simultaneously\r
252 +        * set on the buffer_head.\r
253 +        */\r
254 +       clear_buffer_unwritten(bh);\r
255 +\r
256 +       /*\r
257          * New blocks allocate and/or writing to uninitialized extent\r
258          * will possibly result in updating i_data, so we take\r
259          * the write lock of i_data_sem, and call get_blocks()\r
260 @@ -2180,6 +2200,10 @@ static int ext4_da_get_block_prep(struct\r
261                                   struct buffer_head *bh_result, int create)\r
262  {\r
263         int ret = 0;\r
264 +       sector_t invalid_block = ~((sector_t) 0xffff);\r
265 +\r
266 +       if (invalid_block < ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es))\r
267 +               invalid_block = ~0;\r
268  \r
269         BUG_ON(create == 0);\r
270         BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize);\r
271 @@ -2201,11 +2225,18 @@ static int ext4_da_get_block_prep(struct\r
272                         /* not enough space to reserve */\r
273                         return ret;\r
274  \r
275 -               map_bh(bh_result, inode->i_sb, 0);\r
276 +               map_bh(bh_result, inode->i_sb, invalid_block);\r
277                 set_buffer_new(bh_result);\r
278                 set_buffer_delay(bh_result);\r
279         } else if (ret > 0) {\r
280                 bh_result->b_size = (ret << inode->i_blkbits);\r
281 +               /*\r
282 +                * With sub-block writes into unwritten extents\r
283 +                * we also need to mark the buffer as new so that\r
284 +                * the unwritten parts of the buffer gets correctly zeroed.\r
285 +                */\r
286 +               if (buffer_unwritten(bh_result))\r
287 +                       set_buffer_new(bh_result);\r
288                 ret = 0;\r
289         }\r
290  \r
291 @@ -2493,7 +2524,7 @@ retry:\r
292  \r
293                 ext4_journal_stop(handle);\r
294  \r
295 -               if (mpd.retval == -ENOSPC) {\r
296 +               if ((mpd.retval == -ENOSPC) && sbi->s_journal) {\r
297                         /* commit the transaction which would\r
298                          * free blocks released in the transaction\r
299                          * and try again\r
300 @@ -4167,11 +4243,9 @@ struct inode *ext4_iget(struct super_blo\r
301         ei->i_flags = le32_to_cpu(raw_inode->i_flags);\r
302         inode->i_blocks = ext4_inode_blocks(raw_inode, ei);\r
303         ei->i_file_acl = le32_to_cpu(raw_inode->i_file_acl_lo);\r
304 -       if (EXT4_SB(inode->i_sb)->s_es->s_creator_os !=\r
305 -           cpu_to_le32(EXT4_OS_HURD)) {\r
306 +       if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_64BIT))\r
307                 ei->i_file_acl |=\r
308                         ((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;\r
309 -       }\r
310         inode->i_size = ext4_isize(raw_inode);\r
311         ei->i_disksize = inode->i_size;\r
312         inode->i_generation = le32_to_cpu(raw_inode->i_generation);\r
313 @@ -4218,6 +4292,18 @@ struct inode *ext4_iget(struct super_blo\r
314                         (__u64)(le32_to_cpu(raw_inode->i_version_hi)) << 32;\r
315         }\r
316  \r
317 +       if (ei->i_file_acl &&\r
318 +           ((ei->i_file_acl < \r
319 +             (le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block) +\r
320 +              EXT4_SB(sb)->s_gdb_count)) ||\r
321 +            (ei->i_file_acl >= ext4_blocks_count(EXT4_SB(sb)->s_es)))) {\r
322 +               ext4_error(sb, __func__,\r
323 +                          "bad extended attribute block %llu in inode #%lu",\r
324 +                          ei->i_file_acl, inode->i_ino);\r
325 +               ret = -EIO;\r
326 +               goto bad_inode;\r
327 +       }\r
328 +\r
329         if (S_ISREG(inode->i_mode)) {\r
330                 inode->i_op = &ext4_file_inode_operations;\r
331                 inode->i_fop = &ext4_file_operations;\r
332 @@ -4232,7 +4318,8 @@ struct inode *ext4_iget(struct super_blo\r
333                         inode->i_op = &ext4_symlink_inode_operations;\r
334                         ext4_set_aops(inode);\r
335                 }\r
336 -       } else {\r
337 +       } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) ||\r
338 +             S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {\r
339                 inode->i_op = &ext4_special_inode_operations;\r
340                 if (raw_inode->i_block[0])\r
341                         init_special_inode(inode, inode->i_mode,\r
342 @@ -4240,6 +4327,13 @@ struct inode *ext4_iget(struct super_blo\r
343                 else\r
344                         init_special_inode(inode, inode->i_mode,\r
345                            new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));\r
346 +       } else {\r
347 +               brelse(bh);\r
348 +               ret = -EIO;\r
349 +               ext4_error(inode->i_sb, __func__, \r
350 +                          "bogus i_mode (%o) for inode=%lu",\r
351 +                          inode->i_mode, inode->i_ino);\r
352 +               goto bad_inode;\r
353         }\r
354         brelse(iloc.bh);\r
355         ext4_set_inode_flags(inode);\r
356 diff -uprN linux-2.6.28.orig/fs/ext4/ioctl.c linux-2.6.28/fs/ext4/ioctl.c\r
357 --- linux-2.6.28.orig/fs/ext4/ioctl.c   2009-05-02 20:54:43.000000000 +0200\r
358 +++ linux-2.6.28/fs/ext4/ioctl.c        2009-05-23 16:05:41.000000000 +0200\r
359 @@ -48,8 +48,7 @@ long ext4_ioctl(struct file *filp, unsig\r
360                 if (err)\r
361                         return err;\r
362  \r
363 -               if (!S_ISDIR(inode->i_mode))\r
364 -                       flags &= ~EXT4_DIRSYNC_FL;\r
365 +               flags = ext4_mask_flags(inode->i_mode, flags);\r
366  \r
367                 err = -EPERM;\r
368                 mutex_lock(&inode->i_mutex);\r
369 diff -uprN linux-2.6.28.orig/fs/ext4/mballoc.c linux-2.6.28/fs/ext4/mballoc.c\r
370 --- linux-2.6.28.orig/fs/ext4/mballoc.c 2009-05-02 20:54:43.000000000 +0200\r
371 +++ linux-2.6.28/fs/ext4/mballoc.c      2009-05-23 16:05:41.000000000 +0200\r
372 @@ -1448,7 +1448,7 @@ static void ext4_mb_measure_extent(struc\r
373         struct ext4_free_extent *gex = &ac->ac_g_ex;\r
374  \r
375         BUG_ON(ex->fe_len <= 0);\r
376 -       BUG_ON(ex->fe_len >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));\r
377 +       BUG_ON(ex->fe_len > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));\r
378         BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));\r
379         BUG_ON(ac->ac_status != AC_STATUS_CONTINUE);\r
380  \r
381 @@ -2692,7 +2692,7 @@ int ext4_mb_init(struct super_block *sb,\r
382         i = (sb->s_blocksize_bits + 2) * sizeof(unsigned int);\r
383         sbi->s_mb_maxs = kmalloc(i, GFP_KERNEL);\r
384         if (sbi->s_mb_maxs == NULL) {\r
385 -               kfree(sbi->s_mb_maxs);\r
386 +               kfree(sbi->s_mb_offsets);\r
387                 return -ENOMEM;\r
388         }\r
389  \r
390 @@ -3289,7 +3289,7 @@ ext4_mb_normalize_request(struct ext4_al\r
391         }\r
392         BUG_ON(start + size <= ac->ac_o_ex.fe_logical &&\r
393                         start > ac->ac_o_ex.fe_logical);\r
394 -       BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb));\r
395 +       BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb));\r
396  \r
397         /* now prepare goal request */\r
398  \r
399 @@ -3586,6 +3586,7 @@ static void ext4_mb_put_pa(struct ext4_a\r
400                         struct super_block *sb, struct ext4_prealloc_space *pa)\r
401  {\r
402         unsigned long grp;\r
403 +       ext4_fsblk_t grp_blk;\r
404  \r
405         if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0)\r
406                 return;\r
407 @@ -3600,8 +3601,12 @@ static void ext4_mb_put_pa(struct ext4_a\r
408         pa->pa_deleted = 1;\r
409         spin_unlock(&pa->pa_lock);\r
410  \r
411 -       /* -1 is to protect from crossing allocation group */\r
412 -       ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL);\r
413 +       grp_blk = pa->pa_pstart;\r
414 +       /* If linear, pa_pstart may be in the next group when pa is used up */\r
415 +       if (pa->pa_linear)\r
416 +               grp_blk--;\r
417 +\r
418 +       ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL);\r
419  \r
420         /*\r
421          * possible race:\r
422 @@ -4414,7 +4419,7 @@ static void ext4_mb_add_n_trim(struct ex\r
423                                                 pa_inode_list) {\r
424                 spin_lock(&tmp_pa->pa_lock);\r
425                 if (tmp_pa->pa_deleted) {\r
426 -                       spin_unlock(&pa->pa_lock);\r
427 +                       spin_unlock(&tmp_pa->pa_lock);\r
428                         continue;\r
429                 }\r
430                 if (!added && pa->pa_free < tmp_pa->pa_free) {\r
431 diff -uprN linux-2.6.28.orig/fs/ext4/namei.c linux-2.6.28/fs/ext4/namei.c\r
432 --- linux-2.6.28.orig/fs/ext4/namei.c   2009-05-02 20:54:43.000000000 +0200\r
433 +++ linux-2.6.28/fs/ext4/namei.c        2009-05-23 16:05:41.000000000 +0200\r
434 @@ -1056,8 +1056,16 @@ static struct dentry *ext4_lookup(struct\r
435                         return ERR_PTR(-EIO);\r
436                 }\r
437                 inode = ext4_iget(dir->i_sb, ino);\r
438 -               if (IS_ERR(inode))\r
439 -                       return ERR_CAST(inode);\r
440 +               if (unlikely(IS_ERR(inode))) {\r
441 +                       if (PTR_ERR(inode) == -ESTALE) {\r
442 +                               ext4_error(dir->i_sb, __func__,\r
443 +                                               "deleted inode referenced: %u",\r
444 +                                               ino);\r
445 +                               return ERR_PTR(-EIO);\r
446 +                       } else {\r
447 +                               return ERR_CAST(inode);\r
448 +                       }\r
449 +               }\r
450         }\r
451         return d_splice_alias(inode, dentry);\r
452  }\r
453 @@ -2436,7 +2444,8 @@ static int ext4_rename(struct inode *old\r
454                 ext4_mark_inode_dirty(handle, new_inode);\r
455                 if (!new_inode->i_nlink)\r
456                         ext4_orphan_add(handle, new_inode);\r
457 -               force_da_alloc = 1;\r
458 +               if (!test_opt(new_dir->i_sb, NO_AUTO_DA_ALLOC))\r
459 +                       force_da_alloc = 1;\r
460         }\r
461         retval = 0;\r
462  \r
463 diff -uprN linux-2.6.28.orig/fs/ext4/super.c linux-2.6.28/fs/ext4/super.c\r
464 --- linux-2.6.28.orig/fs/ext4/super.c   2009-05-02 20:54:43.000000000 +0200\r
465 +++ linux-2.6.28/fs/ext4/super.c        2009-05-23 16:05:41.000000000 +0200\r
466 @@ -679,8 +679,6 @@ static int ext4_show_options(struct seq_\r
467         if (!test_opt(sb, POSIX_ACL) && (def_mount_opts & EXT4_DEFM_ACL))\r
468                 seq_puts(seq, ",noacl");\r
469  #endif\r
470 -       if (!test_opt(sb, RESERVATION))\r
471 -               seq_puts(seq, ",noreservation");\r
472         if (sbi->s_commit_interval) {\r
473                 seq_printf(seq, ",commit=%u",\r
474                            (unsigned) (sbi->s_commit_interval / HZ));\r
475 @@ -724,6 +722,9 @@ static int ext4_show_options(struct seq_\r
476         if (test_opt(sb, DATA_ERR_ABORT))\r
477                 seq_puts(seq, ",data_err=abort");\r
478  \r
479 +       if (test_opt(sb, NO_AUTO_DA_ALLOC))\r
480 +               seq_puts(seq, ",auto_da_alloc=0");\r
481 +\r
482         ext4_show_quota_options(seq, sb);\r
483         return 0;\r
484  }\r
485 @@ -849,7 +850,7 @@ enum {\r
486         Opt_resgid, Opt_resuid, Opt_sb, Opt_err_cont, Opt_err_panic, Opt_err_ro,\r
487         Opt_nouid32, Opt_debug, Opt_oldalloc, Opt_orlov,\r
488         Opt_user_xattr, Opt_nouser_xattr, Opt_acl, Opt_noacl,\r
489 -       Opt_reservation, Opt_noreservation, Opt_noload, Opt_nobh, Opt_bh,\r
490 +       Opt_auto_da_alloc, Opt_noload, Opt_nobh, Opt_bh,\r
491         Opt_commit, Opt_journal_update, Opt_journal_inum, Opt_journal_dev,\r
492         Opt_journal_checksum, Opt_journal_async_commit,\r
493         Opt_abort, Opt_data_journal, Opt_data_ordered, Opt_data_writeback,\r
494 @@ -883,8 +884,6 @@ static const match_table_t tokens = {\r
495         {Opt_nouser_xattr, "nouser_xattr"},\r
496         {Opt_acl, "acl"},\r
497         {Opt_noacl, "noacl"},\r
498 -       {Opt_reservation, "reservation"},\r
499 -       {Opt_noreservation, "noreservation"},\r
500         {Opt_noload, "noload"},\r
501         {Opt_nobh, "nobh"},\r
502         {Opt_bh, "bh"},\r
503 @@ -919,6 +918,7 @@ static const match_table_t tokens = {\r
504         {Opt_delalloc, "delalloc"},\r
505         {Opt_nodelalloc, "nodelalloc"},\r
506         {Opt_inode_readahead_blks, "inode_readahead_blks=%u"},\r
507 +       {Opt_auto_da_alloc, "auto_da_alloc=%u"},\r
508         {Opt_err, NULL},\r
509  };\r
510  \r
511 @@ -1049,12 +1049,6 @@ static int parse_options(char *options, \r
512                                "not supported\n");\r
513                         break;\r
514  #endif\r
515 -               case Opt_reservation:\r
516 -                       set_opt(sbi->s_mount_opt, RESERVATION);\r
517 -                       break;\r
518 -               case Opt_noreservation:\r
519 -                       clear_opt(sbi->s_mount_opt, RESERVATION);\r
520 -                       break;\r
521                 case Opt_journal_update:\r
522                         /* @@@ FIXME */\r
523                         /* Eventually we will want to be able to create\r
524 @@ -1331,6 +1325,14 @@ set_qf_format:\r
525                                 return 0;\r
526                         sbi->s_inode_readahead_blks = option;\r
527                         break;\r
528 +               case Opt_auto_da_alloc:\r
529 +                       if (match_int(&args[0], &option))\r
530 +                               return 0;\r
531 +                       if (option)\r
532 +                               clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC);\r
533 +                       else\r
534 +                               set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC);\r
535 +                       break;\r
536                 default:\r
537                         printk(KERN_ERR\r
538                                "EXT4-fs: Unrecognized mount option \"%s\" "\r
539 @@ -1956,7 +1958,6 @@ static int ext4_fill_super(struct super_\r
540         sbi->s_resuid = le16_to_cpu(es->s_def_resuid);\r
541         sbi->s_resgid = le16_to_cpu(es->s_def_resgid);\r
542  \r
543 -       set_opt(sbi->s_mount_opt, RESERVATION);\r
544         set_opt(sbi->s_mount_opt, BARRIER);\r
545  \r
546         /*\r
547 diff -uprN linux-2.6.28.orig/fs/jbd2/revoke.c linux-2.6.28/fs/jbd2/revoke.c\r
548 --- linux-2.6.28.orig/fs/jbd2/revoke.c  2009-05-02 20:54:43.000000000 +0200\r
549 +++ linux-2.6.28/fs/jbd2/revoke.c       2009-05-23 16:05:41.000000000 +0200\r
550 @@ -55,6 +55,25 @@\r
551   *                     need do nothing.\r
552   * RevokeValid set, Revoked set:\r
553   *                     buffer has been revoked.\r
554 + *\r
555 + * Locking rules:\r
556 + * We keep two hash tables of revoke records. One hashtable belongs to the\r
557 + * running transaction (is pointed to by journal->j_revoke), the other one\r
558 + * belongs to the committing transaction. Accesses to the second hash table\r
559 + * happen only from the kjournald and no other thread touches this table.  Also\r
560 + * journal_switch_revoke_table() which switches which hashtable belongs to the\r
561 + * running and which to the committing transaction is called only from\r
562 + * kjournald. Therefore we need no locks when accessing the hashtable belonging\r
563 + * to the committing transaction.\r
564 + *\r
565 + * All users operating on the hash table belonging to the running transaction\r
566 + * have a handle to the transaction. Therefore they are safe from kjournald\r
567 + * switching hash tables under them. For operations on the lists of entries in\r
568 + * the hash table j_revoke_lock is used.\r
569 + *\r
570 + * Finally, also replay code uses the hash tables but at this moment noone else\r
571 + * can touch them (filesystem isn't mounted yet) and hence no locking is\r
572 + * needed.\r
573   */\r
574  \r
575  #ifndef __KERNEL__\r
576 @@ -401,8 +420,6 @@ int jbd2_journal_revoke(handle_t *handle\r
577   * the second time we would still have a pending revoke to cancel.  So,\r
578   * do not trust the Revoked bit on buffers unless RevokeValid is also\r
579   * set.\r
580 - *\r
581 - * The caller must have the journal locked.\r
582   */\r
583  int jbd2_journal_cancel_revoke(handle_t *handle, struct journal_head *jh)\r
584  {\r
585 @@ -480,10 +497,7 @@ void jbd2_journal_switch_revoke_table(jo\r
586  /*\r
587   * Write revoke records to the journal for all entries in the current\r
588   * revoke hash, deleting the entries as we go.\r
589 - *\r
590 - * Called with the journal lock held.\r
591   */\r
592 -\r
593  void jbd2_journal_write_revoke_records(journal_t *journal,\r
594                                   transaction_t *transaction)\r
595  {\r
596 diff -uprN linux-2.6.28.orig/fs/ocfs2/ocfs2_jbd_compat.h linux-2.6.28/fs/ocfs2/ocfs2_jbd_compat.h\r
597 --- linux-2.6.28.orig/fs/ocfs2/ocfs2_jbd_compat.h       2009-05-02 20:54:43.000000000 +0200\r
598 +++ linux-2.6.28/fs/ocfs2/ocfs2_jbd_compat.h    2009-05-23 16:05:41.000000000 +0200\r
599 @@ -60,7 +60,8 @@ static inline int jbd2_journal_file_inod\r
600         return 0;\r
601  }\r
602  \r
603 -static inline int jbd2_journal_begin_ordered_truncate(struct jbd2_inode *inode,\r
604 +static inline int jbd2_journal_begin_ordered_truncate(journal_t *journal,\r
605 +                                                     struct jbd2_inode *inode,\r
606                                                       loff_t new_size)\r
607  {\r
608         return 0;\r