diff options
-rw-r--r-- | fs/ocfs2/resize.c | 12 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.c | 108 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.h | 19 |
3 files changed, 78 insertions, 61 deletions
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c index a2de32a317ad..252baff5eb84 100644 --- a/fs/ocfs2/resize.c +++ b/fs/ocfs2/resize.c | |||
@@ -330,20 +330,14 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters) | |||
330 | lgd_blkno = ocfs2_which_cluster_group(main_bm_inode, | 330 | lgd_blkno = ocfs2_which_cluster_group(main_bm_inode, |
331 | first_new_cluster - 1); | 331 | first_new_cluster - 1); |
332 | 332 | ||
333 | ret = ocfs2_read_block(main_bm_inode, lgd_blkno, &group_bh); | 333 | ret = ocfs2_read_group_descriptor(main_bm_inode, fe, lgd_blkno, |
334 | &group_bh); | ||
334 | if (ret < 0) { | 335 | if (ret < 0) { |
335 | mlog_errno(ret); | 336 | mlog_errno(ret); |
336 | goto out_unlock; | 337 | goto out_unlock; |
337 | } | 338 | } |
338 | |||
339 | group = (struct ocfs2_group_desc *)group_bh->b_data; | 339 | group = (struct ocfs2_group_desc *)group_bh->b_data; |
340 | 340 | ||
341 | ret = ocfs2_check_group_descriptor(inode->i_sb, fe, group); | ||
342 | if (ret) { | ||
343 | mlog_errno(ret); | ||
344 | goto out_unlock; | ||
345 | } | ||
346 | |||
347 | cl_bpc = le16_to_cpu(fe->id2.i_chain.cl_bpc); | 341 | cl_bpc = le16_to_cpu(fe->id2.i_chain.cl_bpc); |
348 | if (le16_to_cpu(group->bg_bits) / cl_bpc + new_clusters > | 342 | if (le16_to_cpu(group->bg_bits) / cl_bpc + new_clusters > |
349 | le16_to_cpu(fe->id2.i_chain.cl_cpg)) { | 343 | le16_to_cpu(fe->id2.i_chain.cl_cpg)) { |
@@ -400,7 +394,7 @@ static int ocfs2_check_new_group(struct inode *inode, | |||
400 | (struct ocfs2_group_desc *)group_bh->b_data; | 394 | (struct ocfs2_group_desc *)group_bh->b_data; |
401 | u16 cl_bpc = le16_to_cpu(di->id2.i_chain.cl_bpc); | 395 | u16 cl_bpc = le16_to_cpu(di->id2.i_chain.cl_bpc); |
402 | 396 | ||
403 | ret = ocfs2_validate_group_descriptor(inode->i_sb, di, gd, 1); | 397 | ret = ocfs2_validate_group_descriptor(inode->i_sb, di, group_bh, 1); |
404 | if (ret) | 398 | if (ret) |
405 | goto out; | 399 | goto out; |
406 | 400 | ||
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index ddba97dc06a0..797f509d7250 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -145,13 +145,13 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl) | |||
145 | return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); | 145 | return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); |
146 | } | 146 | } |
147 | 147 | ||
148 | /* somewhat more expensive than our other checks, so use sparingly. */ | ||
149 | int ocfs2_validate_group_descriptor(struct super_block *sb, | 148 | int ocfs2_validate_group_descriptor(struct super_block *sb, |
150 | struct ocfs2_dinode *di, | 149 | struct ocfs2_dinode *di, |
151 | struct ocfs2_group_desc *gd, | 150 | struct buffer_head *bh, |
152 | int clean_error) | 151 | int clean_error) |
153 | { | 152 | { |
154 | unsigned int max_bits; | 153 | unsigned int max_bits; |
154 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; | ||
155 | 155 | ||
156 | #define do_error(fmt, ...) \ | 156 | #define do_error(fmt, ...) \ |
157 | do{ \ | 157 | do{ \ |
@@ -162,16 +162,32 @@ int ocfs2_validate_group_descriptor(struct super_block *sb, | |||
162 | } while (0) | 162 | } while (0) |
163 | 163 | ||
164 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { | 164 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { |
165 | do_error("Group Descriptor #%llu has bad signature %.*s", | 165 | do_error("Group descriptor #%llu has bad signature %.*s", |
166 | (unsigned long long)le64_to_cpu(gd->bg_blkno), 7, | 166 | (unsigned long long)bh->b_blocknr, 7, |
167 | gd->bg_signature); | 167 | gd->bg_signature); |
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | } | 169 | } |
170 | 170 | ||
171 | if (le64_to_cpu(gd->bg_blkno) != bh->b_blocknr) { | ||
172 | do_error("Group descriptor #%llu has an invalid bg_blkno " | ||
173 | "of %llu", | ||
174 | (unsigned long long)bh->b_blocknr, | ||
175 | (unsigned long long)le64_to_cpu(gd->bg_blkno)); | ||
176 | return -EINVAL; | ||
177 | } | ||
178 | |||
179 | if (le32_to_cpu(gd->bg_generation) != OCFS2_SB(sb)->fs_generation) { | ||
180 | do_error("Group descriptor #%llu has an invalid " | ||
181 | "fs_generation of #%u", | ||
182 | (unsigned long long)bh->b_blocknr, | ||
183 | le32_to_cpu(gd->bg_generation)); | ||
184 | return -EINVAL; | ||
185 | } | ||
186 | |||
171 | if (di->i_blkno != gd->bg_parent_dinode) { | 187 | if (di->i_blkno != gd->bg_parent_dinode) { |
172 | do_error("Group descriptor # %llu has bad parent " | 188 | do_error("Group descriptor #%llu has bad parent " |
173 | "pointer (%llu, expected %llu)", | 189 | "pointer (%llu, expected %llu)", |
174 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 190 | (unsigned long long)bh->b_blocknr, |
175 | (unsigned long long)le64_to_cpu(gd->bg_parent_dinode), | 191 | (unsigned long long)le64_to_cpu(gd->bg_parent_dinode), |
176 | (unsigned long long)le64_to_cpu(di->i_blkno)); | 192 | (unsigned long long)le64_to_cpu(di->i_blkno)); |
177 | return -EINVAL; | 193 | return -EINVAL; |
@@ -179,33 +195,33 @@ int ocfs2_validate_group_descriptor(struct super_block *sb, | |||
179 | 195 | ||
180 | max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc); | 196 | max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc); |
181 | if (le16_to_cpu(gd->bg_bits) > max_bits) { | 197 | if (le16_to_cpu(gd->bg_bits) > max_bits) { |
182 | do_error("Group descriptor # %llu has bit count of %u", | 198 | do_error("Group descriptor #%llu has bit count of %u", |
183 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 199 | (unsigned long long)bh->b_blocknr, |
184 | le16_to_cpu(gd->bg_bits)); | 200 | le16_to_cpu(gd->bg_bits)); |
185 | return -EINVAL; | 201 | return -EINVAL; |
186 | } | 202 | } |
187 | 203 | ||
188 | if (le16_to_cpu(gd->bg_chain) >= | 204 | if (le16_to_cpu(gd->bg_chain) >= |
189 | le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) { | 205 | le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) { |
190 | do_error("Group descriptor # %llu has bad chain %u", | 206 | do_error("Group descriptor #%llu has bad chain %u", |
191 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 207 | (unsigned long long)bh->b_blocknr, |
192 | le16_to_cpu(gd->bg_chain)); | 208 | le16_to_cpu(gd->bg_chain)); |
193 | return -EINVAL; | 209 | return -EINVAL; |
194 | } | 210 | } |
195 | 211 | ||
196 | if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) { | 212 | if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) { |
197 | do_error("Group descriptor # %llu has bit count %u but " | 213 | do_error("Group descriptor #%llu has bit count %u but " |
198 | "claims that %u are free", | 214 | "claims that %u are free", |
199 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 215 | (unsigned long long)bh->b_blocknr, |
200 | le16_to_cpu(gd->bg_bits), | 216 | le16_to_cpu(gd->bg_bits), |
201 | le16_to_cpu(gd->bg_free_bits_count)); | 217 | le16_to_cpu(gd->bg_free_bits_count)); |
202 | return -EINVAL; | 218 | return -EINVAL; |
203 | } | 219 | } |
204 | 220 | ||
205 | if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) { | 221 | if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) { |
206 | do_error("Group descriptor # %llu has bit count %u but " | 222 | do_error("Group descriptor #%llu has bit count %u but " |
207 | "max bitmap bits of %u", | 223 | "max bitmap bits of %u", |
208 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 224 | (unsigned long long)bh->b_blocknr, |
209 | le16_to_cpu(gd->bg_bits), | 225 | le16_to_cpu(gd->bg_bits), |
210 | 8 * le16_to_cpu(gd->bg_size)); | 226 | 8 * le16_to_cpu(gd->bg_size)); |
211 | return -EINVAL; | 227 | return -EINVAL; |
@@ -215,6 +231,30 @@ int ocfs2_validate_group_descriptor(struct super_block *sb, | |||
215 | return 0; | 231 | return 0; |
216 | } | 232 | } |
217 | 233 | ||
234 | int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di, | ||
235 | u64 gd_blkno, struct buffer_head **bh) | ||
236 | { | ||
237 | int rc; | ||
238 | struct buffer_head *tmp = *bh; | ||
239 | |||
240 | rc = ocfs2_read_block(inode, gd_blkno, &tmp); | ||
241 | if (rc) | ||
242 | goto out; | ||
243 | |||
244 | rc = ocfs2_validate_group_descriptor(inode->i_sb, di, tmp, 0); | ||
245 | if (rc) { | ||
246 | brelse(tmp); | ||
247 | goto out; | ||
248 | } | ||
249 | |||
250 | /* If ocfs2_read_block() got us a new bh, pass it up. */ | ||
251 | if (!*bh) | ||
252 | *bh = tmp; | ||
253 | |||
254 | out: | ||
255 | return rc; | ||
256 | } | ||
257 | |||
218 | static int ocfs2_block_group_fill(handle_t *handle, | 258 | static int ocfs2_block_group_fill(handle_t *handle, |
219 | struct inode *alloc_inode, | 259 | struct inode *alloc_inode, |
220 | struct buffer_head *bg_bh, | 260 | struct buffer_head *bg_bh, |
@@ -1177,21 +1217,17 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | |||
1177 | u16 found; | 1217 | u16 found; |
1178 | struct buffer_head *group_bh = NULL; | 1218 | struct buffer_head *group_bh = NULL; |
1179 | struct ocfs2_group_desc *gd; | 1219 | struct ocfs2_group_desc *gd; |
1220 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)ac->ac_bh->b_data; | ||
1180 | struct inode *alloc_inode = ac->ac_inode; | 1221 | struct inode *alloc_inode = ac->ac_inode; |
1181 | 1222 | ||
1182 | ret = ocfs2_read_block(alloc_inode, gd_blkno, &group_bh); | 1223 | ret = ocfs2_read_group_descriptor(alloc_inode, di, gd_blkno, |
1224 | &group_bh); | ||
1183 | if (ret < 0) { | 1225 | if (ret < 0) { |
1184 | mlog_errno(ret); | 1226 | mlog_errno(ret); |
1185 | return ret; | 1227 | return ret; |
1186 | } | 1228 | } |
1187 | 1229 | ||
1188 | gd = (struct ocfs2_group_desc *) group_bh->b_data; | 1230 | gd = (struct ocfs2_group_desc *) group_bh->b_data; |
1189 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { | ||
1190 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, gd); | ||
1191 | ret = -EIO; | ||
1192 | goto out; | ||
1193 | } | ||
1194 | |||
1195 | ret = ac->ac_group_search(alloc_inode, group_bh, bits_wanted, min_bits, | 1231 | ret = ac->ac_group_search(alloc_inode, group_bh, bits_wanted, min_bits, |
1196 | ac->ac_max_block, bit_off, &found); | 1232 | ac->ac_max_block, bit_off, &found); |
1197 | if (ret < 0) { | 1233 | if (ret < 0) { |
@@ -1248,19 +1284,14 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1248 | bits_wanted, chain, | 1284 | bits_wanted, chain, |
1249 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno); | 1285 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno); |
1250 | 1286 | ||
1251 | status = ocfs2_read_block(alloc_inode, | 1287 | status = ocfs2_read_group_descriptor(alloc_inode, fe, |
1252 | le64_to_cpu(cl->cl_recs[chain].c_blkno), | 1288 | le64_to_cpu(cl->cl_recs[chain].c_blkno), |
1253 | &group_bh); | 1289 | &group_bh); |
1254 | if (status < 0) { | 1290 | if (status < 0) { |
1255 | mlog_errno(status); | 1291 | mlog_errno(status); |
1256 | goto bail; | 1292 | goto bail; |
1257 | } | 1293 | } |
1258 | bg = (struct ocfs2_group_desc *) group_bh->b_data; | 1294 | bg = (struct ocfs2_group_desc *) group_bh->b_data; |
1259 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg); | ||
1260 | if (status) { | ||
1261 | mlog_errno(status); | ||
1262 | goto bail; | ||
1263 | } | ||
1264 | 1295 | ||
1265 | status = -ENOSPC; | 1296 | status = -ENOSPC; |
1266 | /* for now, the chain search is a bit simplistic. We just use | 1297 | /* for now, the chain search is a bit simplistic. We just use |
@@ -1278,18 +1309,13 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1278 | next_group = le64_to_cpu(bg->bg_next_group); | 1309 | next_group = le64_to_cpu(bg->bg_next_group); |
1279 | prev_group_bh = group_bh; | 1310 | prev_group_bh = group_bh; |
1280 | group_bh = NULL; | 1311 | group_bh = NULL; |
1281 | status = ocfs2_read_block(alloc_inode, | 1312 | status = ocfs2_read_group_descriptor(alloc_inode, fe, |
1282 | next_group, &group_bh); | 1313 | next_group, &group_bh); |
1283 | if (status < 0) { | 1314 | if (status < 0) { |
1284 | mlog_errno(status); | 1315 | mlog_errno(status); |
1285 | goto bail; | 1316 | goto bail; |
1286 | } | 1317 | } |
1287 | bg = (struct ocfs2_group_desc *) group_bh->b_data; | 1318 | bg = (struct ocfs2_group_desc *) group_bh->b_data; |
1288 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg); | ||
1289 | if (status) { | ||
1290 | mlog_errno(status); | ||
1291 | goto bail; | ||
1292 | } | ||
1293 | } | 1319 | } |
1294 | if (status < 0) { | 1320 | if (status < 0) { |
1295 | if (status != -ENOSPC) | 1321 | if (status != -ENOSPC) |
@@ -1801,18 +1827,14 @@ int ocfs2_free_suballoc_bits(handle_t *handle, | |||
1801 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, count, | 1827 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, count, |
1802 | (unsigned long long)bg_blkno, start_bit); | 1828 | (unsigned long long)bg_blkno, start_bit); |
1803 | 1829 | ||
1804 | status = ocfs2_read_block(alloc_inode, bg_blkno, &group_bh); | 1830 | status = ocfs2_read_group_descriptor(alloc_inode, fe, bg_blkno, |
1831 | &group_bh); | ||
1805 | if (status < 0) { | 1832 | if (status < 0) { |
1806 | mlog_errno(status); | 1833 | mlog_errno(status); |
1807 | goto bail; | 1834 | goto bail; |
1808 | } | 1835 | } |
1809 | |||
1810 | group = (struct ocfs2_group_desc *) group_bh->b_data; | 1836 | group = (struct ocfs2_group_desc *) group_bh->b_data; |
1811 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, group); | 1837 | |
1812 | if (status) { | ||
1813 | mlog_errno(status); | ||
1814 | goto bail; | ||
1815 | } | ||
1816 | BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); | 1838 | BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); |
1817 | 1839 | ||
1818 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, | 1840 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, |
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h index 7adfcc478bdb..43de4fd826d3 100644 --- a/fs/ocfs2/suballoc.h +++ b/fs/ocfs2/suballoc.h | |||
@@ -164,23 +164,24 @@ void ocfs2_free_ac_resource(struct ocfs2_alloc_context *ac); | |||
164 | * and return that block offset. */ | 164 | * and return that block offset. */ |
165 | u64 ocfs2_which_cluster_group(struct inode *inode, u32 cluster); | 165 | u64 ocfs2_which_cluster_group(struct inode *inode, u32 cluster); |
166 | 166 | ||
167 | /* somewhat more expensive than our other checks, so use sparingly. */ | ||
168 | /* | 167 | /* |
169 | * By default, ocfs2_validate_group_descriptor() calls ocfs2_error() when it | 168 | * By default, ocfs2_validate_group_descriptor() calls ocfs2_error() when it |
170 | * finds a problem. A caller that wants to check a group descriptor | 169 | * finds a problem. A caller that wants to check a group descriptor |
171 | * without going readonly passes a nonzero clean_error. This is only | 170 | * without going readonly passes a nonzero clean_error. This is only |
172 | * resize, really. | 171 | * resize, really. Everyone else should be using |
172 | * ocfs2_read_group_descriptor(). | ||
173 | */ | 173 | */ |
174 | int ocfs2_validate_group_descriptor(struct super_block *sb, | 174 | int ocfs2_validate_group_descriptor(struct super_block *sb, |
175 | struct ocfs2_dinode *di, | 175 | struct ocfs2_dinode *di, |
176 | struct ocfs2_group_desc *gd, | 176 | struct buffer_head *bh, |
177 | int clean_error); | 177 | int clean_error); |
178 | static inline int ocfs2_check_group_descriptor(struct super_block *sb, | 178 | /* |
179 | struct ocfs2_dinode *di, | 179 | * Read a group descriptor block into *bh. If *bh is NULL, a bh will be |
180 | struct ocfs2_group_desc *gd) | 180 | * allocated. This is a cached read. The descriptor will be validated with |
181 | { | 181 | * ocfs2_validate_group_descriptor(). |
182 | return ocfs2_validate_group_descriptor(sb, di, gd, 0); | 182 | */ |
183 | } | 183 | int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di, |
184 | u64 gd_blkno, struct buffer_head **bh); | ||
184 | 185 | ||
185 | int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_extent_tree *et, | 186 | int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_extent_tree *et, |
186 | u32 clusters_to_add, u32 extents_to_split, | 187 | u32 clusters_to_add, u32 extents_to_split, |