Whamcloud - gitweb
LU-136 change "force_over_16tb" mount option to "force_over_128tb"
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-block-bitmap-validation-2.6-rhel5.patch
1  fs/ext3/balloc.c |   99 ++++++++++++++++++++++++++++++++++++++++++++----------
2  1 files changed, 81 insertions(+), 18 deletions(-)
3 diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
4 index ff3428e..a9140ea 100644
5 Index: linux-stage/fs/ext3/balloc.c
6 ===================================================================
7 --- linux-stage.orig/fs/ext3/balloc.c
8 +++ linux-stage/fs/ext3/balloc.c
9 @@ -143,9 +143,96 @@ unsigned ext3_init_block_bitmap(struct s
10         return free_blocks - sbi->s_itb_per_group - 2;
11  }
12  
13 -/*
14 - * Read the bitmap for a given block_group, reading into the specified 
15 - * slot in the superblock's bitmap cache.
16 +/**
17 +* bh_uptodate_or_lock: Test whether the buffer is uptodate
18 +* @bh: struct buffer_head
19 +*
20 +* Return true if the buffer is up-to-date and false,
21 +* with the buffer locked, if not.
22 +*/
23 +int bh_uptodate_or_lock(struct buffer_head *bh)
24 +{
25 +       if (!buffer_uptodate(bh)) {
26 +               lock_buffer(bh);
27 +               if (!buffer_uptodate(bh))
28 +                       return 0;
29 +               unlock_buffer(bh);
30 +       }
31 +       return 1;
32 +}
33 +
34 +/**
35 +* bh_submit_read: Submit a locked buffer for reading
36 +* @bh: struct buffer_head
37 +*
38 +* Returns a negative error
39 +*/
40 +int bh_submit_read(struct buffer_head *bh)
41 +{
42 +       if (!buffer_locked(bh))
43 +               lock_buffer(bh);
44 +       if (buffer_uptodate(bh))
45 +               return 0;
46 +       get_bh(bh);
47 +       bh->b_end_io = end_buffer_read_sync;
48 +       submit_bh(READ, bh);
49 +       wait_on_buffer(bh);
50 +       if (buffer_uptodate(bh))
51 +               return 0;
52 +       return -EIO;
53 +}
54 +
55 +static int ext3_valid_block_bitmap(struct super_block *sb,
56 +                                  struct ext3_group_desc *desc,
57 +                                  unsigned int block_group,
58 +                                  struct buffer_head *bh)
59 +{
60 +       ext3_grpblk_t offset;
61 +       ext3_grpblk_t next_zero_bit;
62 +       ext3_fsblk_t bitmap_blk;
63 +       ext3_fsblk_t group_first_block;
64 +
65 +       group_first_block = ext3_group_first_block_no(sb, block_group);
66 +
67 +       /* check whether block bitmap block number is set */
68 +       bitmap_blk = le32_to_cpu(desc->bg_block_bitmap);
69 +       offset = bitmap_blk - group_first_block;
70 +       if (!ext3_test_bit(offset, bh->b_data))
71 +               /* bad block bitmap */
72 +               goto err_out;
73 +
74 +       /* check whether the inode bitmap block number is set */
75 +       bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap);
76 +       offset = bitmap_blk - group_first_block;
77 +       if (!ext3_test_bit(offset, bh->b_data))
78 +               /* bad block bitmap */
79 +               goto err_out;
80 +
81 +       /* check whether the inode table block number is set */
82 +       bitmap_blk = le32_to_cpu(desc->bg_inode_table);
83 +       offset = bitmap_blk - group_first_block;
84 +       next_zero_bit = ext3_find_next_zero_bit(bh->b_data,
85 +                               offset + EXT3_SB(sb)->s_itb_per_group,
86 +                               offset);
87 +       if (next_zero_bit >= offset + EXT3_SB(sb)->s_itb_per_group)
88 +               /* good bitmap for inode tables */
89 +               return 1;
90 +
91 +err_out:
92 +       ext3_error(sb, __FUNCTION__,
93 +                  "Invalid block bitmap - "
94 +                  "block_group = %d, block = %lu",
95 +                  (int)block_group, bitmap_blk);
96 +       return 0;
97 +}
98 +
99 +/**
100 + * read_block_bitmap()
101 + * @sb:                 super block
102 + * @block_group: given block group
103 + *
104 + * Read the bitmap for a given block_group,and validate the
105 + * bits for block/inode/inode tables are set in the bitmaps.
106   *
107   * Return buffer_head on success or NULL in case of failure.
108   */
109 @@ -154,29 +241,42 @@ read_block_bitmap(struct super_block *sb
110  {
111         struct ext3_group_desc * desc;
112         struct buffer_head * bh = NULL;
113 +       ext3_fsblk_t bitmap_blk;
114  
115         desc = ext3_get_group_desc (sb, block_group, NULL);
116         if (!desc)
117 -               goto error_out;
118 +               return NULL;
119 +       bitmap_blk = desc->bg_block_bitmap;
120 +       bh = sb_getblk(sb, bitmap_blk);
121 +       if (unlikely(!bh)) {
122 +               ext3_error(sb, __FUNCTION__,
123 +                          "Can not read block bitmap - "
124 +                          "block group = %d, block_bitmap = %lu",
125 +                          (int)block_group, bitmap_blk);
126 +               return NULL;
127 +       }
128 +       if (bh_uptodate_or_lock(bh))
129 +               return bh;
130 +
131         if (desc->bg_flags & cpu_to_le16(EXT3_BG_BLOCK_UNINIT)) {
132 -               bh = sb_getblk(sb, le32_to_cpu(desc->bg_block_bitmap));
133 -               if (!buffer_uptodate(bh)) {
134 -                       lock_buffer(bh);
135 -                       if (!buffer_uptodate(bh)) {
136 -                               ext3_init_block_bitmap(sb, bh,block_group,desc);
137 -                               set_buffer_uptodate(bh);
138 -                       }
139 -                       unlock_buffer(bh);
140 -               }
141 -       } else {
142 -               bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap));
143 +               ext3_init_block_bitmap(sb, bh, block_group, desc);
144 +               set_buffer_uptodate(bh);
145 +               unlock_buffer(bh);
146 +               return bh;
147 +       }
148 +       if (bh_submit_read(bh) < 0) {
149 +               brelse(bh);
150 +               ext3_error(sb, __FUNCTION__,
151 +                          "Cannot read block bitmap - "
152 +                          "block group = %d block_bitmap = %lu",
153 +                          (int)block_group, bitmap_blk);
154 +               return NULL;
155 +       }
156 +       if (!ext3_valid_block_bitmap(sb, desc, block_group, bh)) {
157 +               brelse(bh);
158 +               return NULL;
159         }
160 -       if (!bh)
161 -               ext3_error (sb, "read_block_bitmap",
162 -                           "Cannot read block bitmap - "
163 -                           "block_group = %d, block_bitmap = %u",
164 -                           block_group, le32_to_cpu(desc->bg_block_bitmap));
165 -error_out:
166 +
167         return bh;
168  }
169  /*