diff options
Diffstat (limited to 'fs/xfs/xfs_ialloc_btree.c')
-rw-r--r-- | fs/xfs/xfs_ialloc_btree.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index 2b8b7a37aa18..bec344b36507 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "xfs_ialloc.h" | 33 | #include "xfs_ialloc.h" |
34 | #include "xfs_alloc.h" | 34 | #include "xfs_alloc.h" |
35 | #include "xfs_error.h" | 35 | #include "xfs_error.h" |
36 | #include "xfs_trace.h" | ||
36 | 37 | ||
37 | 38 | ||
38 | STATIC int | 39 | STATIC int |
@@ -181,6 +182,59 @@ xfs_inobt_key_diff( | |||
181 | cur->bc_rec.i.ir_startino; | 182 | cur->bc_rec.i.ir_startino; |
182 | } | 183 | } |
183 | 184 | ||
185 | void | ||
186 | xfs_inobt_verify( | ||
187 | struct xfs_buf *bp) | ||
188 | { | ||
189 | struct xfs_mount *mp = bp->b_target->bt_mount; | ||
190 | struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); | ||
191 | unsigned int level; | ||
192 | int sblock_ok; /* block passes checks */ | ||
193 | |||
194 | /* magic number and level verification */ | ||
195 | level = be16_to_cpu(block->bb_level); | ||
196 | sblock_ok = block->bb_magic == cpu_to_be32(XFS_IBT_MAGIC) && | ||
197 | level < mp->m_in_maxlevels; | ||
198 | |||
199 | /* numrecs verification */ | ||
200 | sblock_ok = sblock_ok && | ||
201 | be16_to_cpu(block->bb_numrecs) <= mp->m_inobt_mxr[level != 0]; | ||
202 | |||
203 | /* sibling pointer verification */ | ||
204 | sblock_ok = sblock_ok && | ||
205 | (block->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK) || | ||
206 | be32_to_cpu(block->bb_u.s.bb_leftsib) < mp->m_sb.sb_agblocks) && | ||
207 | block->bb_u.s.bb_leftsib && | ||
208 | (block->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK) || | ||
209 | be32_to_cpu(block->bb_u.s.bb_rightsib) < mp->m_sb.sb_agblocks) && | ||
210 | block->bb_u.s.bb_rightsib; | ||
211 | |||
212 | if (!sblock_ok) { | ||
213 | trace_xfs_btree_corrupt(bp, _RET_IP_); | ||
214 | XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, block); | ||
215 | xfs_buf_ioerror(bp, EFSCORRUPTED); | ||
216 | } | ||
217 | } | ||
218 | |||
219 | static void | ||
220 | xfs_inobt_read_verify( | ||
221 | struct xfs_buf *bp) | ||
222 | { | ||
223 | xfs_inobt_verify(bp); | ||
224 | } | ||
225 | |||
226 | static void | ||
227 | xfs_inobt_write_verify( | ||
228 | struct xfs_buf *bp) | ||
229 | { | ||
230 | xfs_inobt_verify(bp); | ||
231 | } | ||
232 | |||
233 | const struct xfs_buf_ops xfs_inobt_buf_ops = { | ||
234 | .verify_read = xfs_inobt_read_verify, | ||
235 | .verify_write = xfs_inobt_write_verify, | ||
236 | }; | ||
237 | |||
184 | #ifdef DEBUG | 238 | #ifdef DEBUG |
185 | STATIC int | 239 | STATIC int |
186 | xfs_inobt_keys_inorder( | 240 | xfs_inobt_keys_inorder( |
@@ -218,6 +272,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = { | |||
218 | .init_rec_from_cur = xfs_inobt_init_rec_from_cur, | 272 | .init_rec_from_cur = xfs_inobt_init_rec_from_cur, |
219 | .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, | 273 | .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, |
220 | .key_diff = xfs_inobt_key_diff, | 274 | .key_diff = xfs_inobt_key_diff, |
275 | .buf_ops = &xfs_inobt_buf_ops, | ||
221 | #ifdef DEBUG | 276 | #ifdef DEBUG |
222 | .keys_inorder = xfs_inobt_keys_inorder, | 277 | .keys_inorder = xfs_inobt_keys_inorder, |
223 | .recs_inorder = xfs_inobt_recs_inorder, | 278 | .recs_inorder = xfs_inobt_recs_inorder, |