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