Whamcloud - gitweb
a8b4e380f3b54cbc05bdbd067e9da7bf727f7ad3
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / rhel7 / ext4-corrupted-inode-block-bitmaps-handling-patches.patch
1 Since we could skip corrupt block groups, this patch
2 use ext4_warning() intead of ext4_error() to make FS not
3 emount RO in default, also fix a leftover from upstream
4 commit 163a203ddb36c36d4a1c942
5 ---
6 diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
7 index e069155..692b5e4 100644
8 --- a/fs/ext4/balloc.c
9 +++ b/fs/ext4/balloc.c
10 @@ -185,25 +185,17 @@ static int ext4_init_block_bitmap(struct super_block *sb,
11         struct ext4_sb_info *sbi = EXT4_SB(sb);
12         ext4_fsblk_t start, tmp;
13         int flex_bg = 0;
14 -       struct ext4_group_info *grp;
15  
16         J_ASSERT_BH(bh, buffer_locked(bh));
17  
18         /* If checksum is bad mark all blocks used to prevent allocation
19          * essentially implementing a per-group read-only flag. */
20         if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
21 -               grp = ext4_get_group_info(sb, block_group);
22 -               if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
23 -                       percpu_counter_sub(&sbi->s_freeclusters_counter,
24 -                                          grp->bb_free);
25 -               set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
26 -               if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
27 -                       int count;
28 -                       count = ext4_free_inodes_count(sb, gdp);
29 -                       percpu_counter_sub(&sbi->s_freeinodes_counter,
30 -                                          count);
31 -               }
32 -               set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
33 +               ext4_corrupted_block_group(sb, block_group,
34 +                               EXT4_GROUP_INFO_BBITMAP_CORRUPT |
35 +                               EXT4_GROUP_INFO_IBITMAP_CORRUPT,
36 +                               "Checksum bad for group %u",
37 +                               block_group);
38                 return -EIO;
39         }
40         memset(bh->b_data, 0, sb->s_blocksize);
41 @@ -367,8 +359,6 @@ static void ext4_validate_block_bitmap(struct super_block *sb,
42                                        struct buffer_head *bh)
43  {
44         ext4_fsblk_t    blk;
45 -       struct ext4_group_info *grp = ext4_get_group_info(sb, block_group);
46 -       struct ext4_sb_info *sbi = EXT4_SB(sb);
47  
48         if (buffer_verified(bh))
49                 return;
50 @@ -377,22 +367,19 @@ static void ext4_validate_block_bitmap(struct super_block *sb,
51         blk = ext4_valid_block_bitmap(sb, desc, block_group, bh);
52         if (unlikely(blk != 0)) {
53                 ext4_unlock_group(sb, block_group);
54 -               ext4_error(sb, "bg %u: block %llu: invalid block bitmap",
55 -                          block_group, blk);
56 -               if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
57 -                       percpu_counter_sub(&sbi->s_freeclusters_counter,
58 -                                          grp->bb_free);
59 -               set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
60 +               ext4_corrupted_block_group(sb, block_group,
61 +                               EXT4_GROUP_INFO_BBITMAP_CORRUPT,
62 +                               "bg %u: block %llu: invalid block bitmap",
63 +                               block_group, blk);
64                 return;
65         }
66         if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group,
67                         desc, bh))) {
68                 ext4_unlock_group(sb, block_group);
69 -               ext4_error(sb, "bg %u: bad block bitmap checksum", block_group);
70 -               if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
71 -                       percpu_counter_sub(&sbi->s_freeclusters_counter,
72 -                                          grp->bb_free);
73 -               set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
74 +               ext4_corrupted_block_group(sb, block_group,
75 +                               EXT4_GROUP_INFO_BBITMAP_CORRUPT,
76 +                               "bg %u: bad block bitmap checksum",
77 +                               block_group);
78                 return;
79         }
80         set_buffer_verified(bh);
81 @@ -445,8 +432,6 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
82                 set_buffer_uptodate(bh);
83                 ext4_unlock_group(sb, block_group);
84                 unlock_buffer(bh);
85 -               if (err)
86 -                       ext4_error(sb, "Checksum bad for grp %u", block_group);
87                 return bh;
88         }
89         ext4_unlock_group(sb, block_group);
90 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
91 index 3c41773..63a63b6 100644
92 --- a/fs/ext4/ext4.h
93 +++ b/fs/ext4/ext4.h
94 @@ -91,6 +91,17 @@ typedef __u32 ext4_lblk_t;
95  /* data type for block group number */
96  typedef unsigned int ext4_group_t;
97  
98 +void __ext4_corrupted_block_group(struct super_block *sb,
99 +                                 ext4_group_t group, unsigned int flags,
100 +                                 const char *function, unsigned int line);
101 +
102 +#define ext4_corrupted_block_group(sb, group, flags, fmt, ...)         \
103 +       do {                                                            \
104 +               __ext4_warning(sb, __func__, __LINE__, fmt,             \
105 +                               ##__VA_ARGS__);                         \
106 +               __ext4_corrupted_block_group(sb, group, flags,          \
107 +                                       __func__, __LINE__);            \
108 +       } while (0)
109  /*
110   * Flags used in mballoc's allocation_context flags field.
111   *
112 @@ -2673,7 +2684,11 @@ struct ext4_group_info {
113  #define EXT4_GROUP_INFO_NEED_INIT_BIT          0
114  #define EXT4_GROUP_INFO_WAS_TRIMMED_BIT                1
115  #define EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT    2
116 +#define EXT4_GROUP_INFO_BBITMAP_CORRUPT                \
117 +       (1 << EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT)
118  #define EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT    3
119 +#define EXT4_GROUP_INFO_IBITMAP_CORRUPT                \
120 +       (1 << EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT)
121  
122  #define EXT4_MB_GRP_NEED_INIT(grp)     \
123         (test_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &((grp)->bb_state)))
124 diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
125 index fc65310..92bcc8d 100644
126 --- a/fs/ext4/ialloc.c
127 +++ b/fs/ext4/ialloc.c
128 @@ -70,26 +70,15 @@ static unsigned ext4_init_inode_bitmap(struct super_block *sb,
129                                        ext4_group_t block_group,
130                                        struct ext4_group_desc *gdp)
131  {
132 -       struct ext4_group_info *grp;
133 -       struct ext4_sb_info *sbi = EXT4_SB(sb);
134         J_ASSERT_BH(bh, buffer_locked(bh));
135  
136         /* If checksum is bad mark all blocks and inodes use to prevent
137          * allocation, essentially implementing a per-group read-only flag. */
138         if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
139 -               ext4_error(sb, "Checksum bad for group %u", block_group);
140 -               grp = ext4_get_group_info(sb, block_group);
141 -               if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
142 -                       percpu_counter_sub(&sbi->s_freeclusters_counter,
143 -                                          grp->bb_free);
144 -               set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT, &grp->bb_state);
145 -               if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
146 -                       int count;
147 -                       count = ext4_free_inodes_count(sb, gdp);
148 -                       percpu_counter_sub(&sbi->s_freeinodes_counter,
149 -                                          count);
150 -               }
151 -               set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
152 +               ext4_corrupted_block_group(sb, block_group,
153 +                               EXT4_GROUP_INFO_BBITMAP_CORRUPT |
154 +                               EXT4_GROUP_INFO_IBITMAP_CORRUPT,
155 +                               "Checksum bad for group %u", block_group);
156                 return 0;
157         }
158  
159 @@ -125,8 +114,6 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
160         struct ext4_group_desc *desc;
161         struct buffer_head *bh = NULL;
162         ext4_fsblk_t bitmap_blk;
163 -       struct ext4_group_info *grp;
164 -       struct ext4_sb_info *sbi = EXT4_SB(sb);
165  
166         desc = ext4_get_group_desc(sb, block_group, NULL);
167         if (!desc)
168 @@ -193,16 +180,10 @@ verify:
169                                            EXT4_INODES_PER_GROUP(sb) / 8)) {
170                 ext4_unlock_group(sb, block_group);
171                 put_bh(bh);
172 -               ext4_error(sb, "Corrupt inode bitmap - block_group = %u, "
173 -                          "inode_bitmap = %llu", block_group, bitmap_blk);
174 -               grp = ext4_get_group_info(sb, block_group);
175 -               if (!EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
176 -                       int count;
177 -                       count = ext4_free_inodes_count(sb, desc);
178 -                       percpu_counter_sub(&sbi->s_freeinodes_counter,
179 -                                          count);
180 -               }
181 -               set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
182 +               ext4_corrupted_block_group(sb, block_group,
183 +                               EXT4_GROUP_INFO_IBITMAP_CORRUPT,
184 +                               "Corrupt inode bitmap - block_group = %u, inode_bitmap = %llu",
185 +                               block_group, bitmap_blk);
186                 return NULL;
187         }
188         ext4_unlock_group(sb, block_group);
189 @@ -337,14 +318,9 @@ out:
190                 if (!fatal)
191                         fatal = err;
192         } else {
193 -               ext4_error(sb, "bit already cleared for inode %lu", ino);
194 -               if (gdp && !EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
195 -                       int count;
196 -                       count = ext4_free_inodes_count(sb, gdp);
197 -                       percpu_counter_sub(&sbi->s_freeinodes_counter,
198 -                                          count);
199 -               }
200 -               set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
201 +               ext4_corrupted_block_group(sb, block_group,
202 +                               EXT4_GROUP_INFO_IBITMAP_CORRUPT,
203 +                               "bit already cleared for inode %lu", ino);
204         }
205  
206  error_return:
207 diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
208 index 7282d07..e6805e6 100644
209 --- a/fs/ext4/mballoc.c
210 +++ b/fs/ext4/mballoc.c
211 @@ -752,10 +752,18 @@ int ext4_mb_generate_buddy(struct super_block *sb,
212         if (free != grp->bb_free) {
213                 struct ext4_group_desc *gdp;
214                 gdp = ext4_get_group_desc(sb, group, NULL);
215 -               ext4_error(sb, "group %lu: %u blocks in bitmap, %u in bb, "
216 -                       "%u in gd, %lu pa's\n", (long unsigned int)group,
217 -                       free, grp->bb_free, ext4_free_group_clusters(sb, gdp),
218 -                       grp->bb_prealloc_nr);
219 +
220 +               ext4_corrupted_block_group(sb, group,
221 +                               EXT4_GROUP_INFO_BBITMAP_CORRUPT,
222 +                               "group %lu: %u blocks in bitmap, %u in bb, %u in gd, %lu pa's block bitmap corrupt",
223 +                               (unsigned long int)group, free, grp->bb_free,
224 +                               ext4_free_group_clusters(sb, gdp),
225 +                               grp->bb_prealloc_nr);
226 +               /*
227 +                * If we intend to continue, we consider group descriptor
228 +                * corrupt and update bb_free using bitmap value
229 +                */
230 +               grp->bb_free = free;
231                 return -EIO;
232         }
233         mb_set_largest_free_order(sb, grp);
234 @@ -1101,7 +1109,7 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
235         int block;
236         int pnum;
237         int poff;
238 -       struct page *page;
239 +       struct page *page = NULL;
240         int ret;
241         struct ext4_group_info *grp;
242         struct ext4_sb_info *sbi = EXT4_SB(sb);
243 @@ -1127,7 +1135,7 @@ ext4_mb_load_buddy(struct super_block *sb, ext4_group_t group,
244                  */
245                 ret = ext4_mb_init_group(sb, group);
246                 if (ret)
247 -                       return ret;
248 +                       goto err;
249         }
250  
251         /*
252 @@ -1227,6 +1235,7 @@ err:
253                 page_cache_release(e4b->bd_buddy_page);
254         e4b->bd_buddy = NULL;
255         e4b->bd_bitmap = NULL;
256 +       ext4_warning(sb, "Error loading buddy information for %u", group);
257         return ret;
258  }
259  
260 @@ -3599,9 +3608,11 @@ int ext4_mb_check_ondisk_bitmap(struct super_block *sb, void *bitmap,
261         }
262  
263         if (free != ext4_free_group_clusters(sb, gdp)) {
264 -               ext4_error(sb, "on-disk bitmap for group %d"
265 -                       "corrupted: %u blocks free in bitmap, %u - in gd\n",
266 -                       group, free, ext4_free_group_clusters(sb, gdp));
267 +               ext4_corrupted_block_group(sb, group,
268 +                               EXT4_GROUP_INFO_BBITMAP_CORRUPT,
269 +                               "on-disk bitmap for group %d corrupted: %u blocks free in bitmap, %u - in gd\n",
270 +                               group, free,
271 +                               ext4_free_group_clusters(sb, gdp));
272                 return -EIO;
273         }
274         return 0;
275 @@ -3962,16 +3973,8 @@ ext4_mb_release_inode_pa(struct ext4_buddy *e4b, struct buffer_head *bitmap_bh,
276         /* "free < pa->pa_free" means we maybe double alloc the same blocks,
277          * otherwise maybe leave some free blocks unavailable, no need to BUG.*/
278         if ((free > pa->pa_free && !pa->pa_error) || (free < pa->pa_free)) {
279 -               ext4_error(sb, "pa free mismatch: [pa %p] "
280 -                               "[phy %lu] [logic %lu] [len %u] [free %u] "
281 -                               "[error %u] [inode %lu] [freed %u]", pa,
282 -                               (unsigned long)pa->pa_pstart,
283 -                               (unsigned long)pa->pa_lstart,
284 -                               (unsigned)pa->pa_len, (unsigned)pa->pa_free,
285 -                               (unsigned)pa->pa_error, pa->pa_inode->i_ino,
286 -                               free);
287                 ext4_grp_locked_error(sb, group, 0, 0, "free %u, pa_free %u",
288 -                                       free, pa->pa_free);
289 +                                     free, pa->pa_free);
290                 /*
291                  * pa is already deleted so we use the value obtained
292                  * from the bitmap and continue.
293 @@ -4031,14 +4034,11 @@ ext4_mb_discard_group_preallocations(struct super_block *sb,
294                 return 0;
295  
296         bitmap_bh = ext4_read_block_bitmap(sb, group);
297 -       if (bitmap_bh == NULL) {
298 -               ext4_error(sb, "Error reading block bitmap for %u", group);
299 +       if (bitmap_bh == NULL)
300                 return 0;
301 -       }
302  
303         err = ext4_mb_load_buddy(sb, group, &e4b);
304         if (err) {
305 -               ext4_error(sb, "Error loading buddy information for %u", group);
306                 put_bh(bitmap_bh);
307                 return 0;
308         }
309 @@ -4198,16 +4198,11 @@ repeat:
310                 group = ext4_get_group_number(sb, pa->pa_pstart);
311  
312                 err = ext4_mb_load_buddy(sb, group, &e4b);
313 -               if (err) {
314 -                       ext4_error(sb, "Error loading buddy information for %u",
315 -                                       group);
316 +               if (err)
317                         return;
318 -               }
319  
320                 bitmap_bh = ext4_read_block_bitmap(sb, group);
321                 if (bitmap_bh == NULL) {
322 -                       ext4_error(sb, "Error reading block bitmap for %u",
323 -                                       group);
324                         ext4_mb_unload_buddy(&e4b);
325                         continue;
326                 }
327 @@ -4467,11 +4462,8 @@ ext4_mb_discard_lg_preallocations(struct super_block *sb,
328         list_for_each_entry_safe(pa, tmp, &discard_list, u.pa_tmp_list) {
329  
330                 group = ext4_get_group_number(sb, pa->pa_pstart);
331 -               if (ext4_mb_load_buddy(sb, group, &e4b)) {
332 -                       ext4_error(sb, "Error loading buddy information for %u",
333 -                                       group);
334 +               if (ext4_mb_load_buddy(sb, group, &e4b))
335                         continue;
336 -               }
337                 ext4_lock_group(sb, group);
338                 list_del(&pa->pa_group_list);
339                 ext4_get_group_info(sb, group)->bb_prealloc_nr--;
340 @@ -4742,17 +4734,18 @@ errout:
341                          * been updated or not when fail case. So can
342                          * not revert pa_free back, just mark pa_error*/
343                         pa->pa_error++;
344 -                       ext4_error(sb,
345 -                               "Updating bitmap error: [err %d] "
346 -                               "[pa %p] [phy %lu] [logic %lu] "
347 -                               "[len %u] [free %u] [error %u] "
348 -                               "[inode %lu]", *errp, pa,
349 -                               (unsigned long)pa->pa_pstart,
350 -                               (unsigned long)pa->pa_lstart,
351 -                               (unsigned)pa->pa_len,
352 -                               (unsigned)pa->pa_free,
353 -                               (unsigned)pa->pa_error,
354 -                               pa->pa_inode ? pa->pa_inode->i_ino : 0);
355 +                       ext4_corrupted_block_group(sb, 0, 0,
356 +                                       "Updating bitmap error: [err %d] "
357 +                                       "[pa %p] [phy %lu] [logic %lu] "
358 +                                       "[len %u] [free %u] [error %u] "
359 +                                       "[inode %lu]", *errp, pa,
360 +                                       (unsigned long)pa->pa_pstart,
361 +                                       (unsigned long)pa->pa_lstart,
362 +                                       (unsigned)pa->pa_len,
363 +                                       (unsigned)pa->pa_free,
364 +                                       (unsigned)pa->pa_error,
365 +                                       pa->pa_inode ?
366 +                                       pa->pa_inode->i_ino : 0);
367                 }
368         }
369         ext4_mb_release_context(ac);
370 @@ -5037,7 +5030,7 @@ do_more:
371  
372         err = ext4_mb_load_buddy(sb, block_group, &e4b);
373         if (err)
374 -               goto error_return;
375 +               goto error_brelse;
376  
377         if ((flags & EXT4_FREE_BLOCKS_METADATA) && ext4_handle_valid(handle)) {
378                 struct ext4_free_data *new_entry;
379 @@ -5119,8 +5112,9 @@ do_more:
380                 goto do_more;
381         }
382  error_return:
383 -       brelse(bitmap_bh);
384         ext4_std_error(sb, err);
385 +error_brelse:
386 +       brelse(bitmap_bh);
387         return;
388  }
389  
390 @@ -5216,7 +5210,7 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
391  
392         err = ext4_mb_load_buddy(sb, block_group, &e4b);
393         if (err)
394 -               goto error_return;
395 +               goto error_brelse;
396  
397         /*
398          * need to update group_info->bb_free and bitmap
399 @@ -5253,8 +5247,9 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
400                 err = ret;
401  
402  error_return:
403 -       brelse(bitmap_bh);
404         ext4_std_error(sb, err);
405 +error_brelse:
406 +       brelse(bitmap_bh);
407         return err;
408  }
409  
410 @@ -5329,11 +5324,9 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
411         trace_ext4_trim_all_free(sb, group, start, max);
412  
413         ret = ext4_mb_load_buddy(sb, group, &e4b);
414 -       if (ret) {
415 -               ext4_error(sb, "Error in loading buddy "
416 -                               "information for %u", group);
417 +       if (ret)
418                 return ret;
419 -       }
420 +
421         bitmap = e4b.bd_bitmap;
422  
423         ext4_lock_group(sb, group);
424 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
425 index c625960..0de22f2 100644
426 --- a/fs/ext4/super.c
427 +++ b/fs/ext4/super.c
428 @@ -633,6 +633,37 @@ void __ext4_warning(struct super_block *sb, const char *function,
429         va_end(args);
430  }
431  
432 +void __ext4_corrupted_block_group(struct super_block *sb, ext4_group_t group,
433 +                                 unsigned int flags, const char *function,
434 +                                 unsigned int line)
435 +{
436 +       struct ext4_sb_info *sbi = EXT4_SB(sb);
437 +       struct ext4_group_info *grp = ext4_get_group_info(sb, group);
438 +       struct ext4_group_desc *gdp = ext4_get_group_desc(sb, group, NULL);
439 +
440 +       if (flags & EXT4_GROUP_INFO_BBITMAP_CORRUPT &&
441 +           !EXT4_MB_GRP_BBITMAP_CORRUPT(grp)) {
442 +               percpu_counter_sub(&sbi->s_freeclusters_counter,
443 +                                       grp->bb_free);
444 +               set_bit(EXT4_GROUP_INFO_BBITMAP_CORRUPT_BIT,
445 +                       &grp->bb_state);
446 +       }
447 +
448 +       if (flags & EXT4_GROUP_INFO_IBITMAP_CORRUPT &&
449 +           !EXT4_MB_GRP_IBITMAP_CORRUPT(grp)) {
450 +               if (gdp) {
451 +                       int count;
452 +
453 +                       count = ext4_free_inodes_count(sb, gdp);
454 +                       percpu_counter_sub(&sbi->s_freeinodes_counter,
455 +                                          count);
456 +               }
457 +               set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT,
458 +                       &grp->bb_state);
459 +       }
460 +       save_error_info(sb, function, line);
461 +}
462 +
463  void __ext4_grp_locked_error(const char *function, unsigned int line,
464                              struct super_block *sb, ext4_group_t grp,
465                              unsigned long ino, ext4_fsblk_t block,