aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@sgi.com>2008-03-27 03:01:14 -0400
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-04-17 21:49:51 -0400
commit2abdb8c88110bab78bfe17e51346e735560daa02 (patch)
tree0fad752a8f931991f0a788d52aeaaee508c0c3ea /fs
parent433550990e6c2e94995239bac6a52b4df454cae0 (diff)
[XFS] Prevent xfs_bmap_check_leaf_extents() referencing unmapped memory.
While investigating the extent corruption bug I ran into this bug in debug only code. xfs_bmap_check_leaf_extents() loops through the leaf blocks of the extent btree checking that every extent is entirely before the next extent. It also compares the last extent in the previous block to the first extent in the current block when the previous block has been released and potentially unmapped. So take a copy of the last extent instead of a pointer. Also move the last extent check out of the loop because we only need to do it once. SGI-PV: 976035 SGI-Modid: xfs-linux-melb:xfs-kern:30718a Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_bmap.c15
1 files changed, 6 insertions, 9 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index bce8e3bd8ad1..7d683e0b8ef7 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -6194,7 +6194,7 @@ xfs_bmap_check_leaf_extents(
6194 xfs_mount_t *mp; /* file system mount structure */ 6194 xfs_mount_t *mp; /* file system mount structure */
6195 __be64 *pp; /* pointer to block address */ 6195 __be64 *pp; /* pointer to block address */
6196 xfs_bmbt_rec_t *ep; /* pointer to current extent */ 6196 xfs_bmbt_rec_t *ep; /* pointer to current extent */
6197 xfs_bmbt_rec_t *lastp; /* pointer to previous extent */ 6197 xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */
6198 xfs_bmbt_rec_t *nextp; /* pointer to next extent */ 6198 xfs_bmbt_rec_t *nextp; /* pointer to next extent */
6199 int bp_release = 0; 6199 int bp_release = 0;
6200 6200
@@ -6264,7 +6264,6 @@ xfs_bmap_check_leaf_extents(
6264 /* 6264 /*
6265 * Loop over all leaf nodes checking that all extents are in the right order. 6265 * Loop over all leaf nodes checking that all extents are in the right order.
6266 */ 6266 */
6267 lastp = NULL;
6268 for (;;) { 6267 for (;;) {
6269 xfs_fsblock_t nextbno; 6268 xfs_fsblock_t nextbno;
6270 xfs_extnum_t num_recs; 6269 xfs_extnum_t num_recs;
@@ -6285,18 +6284,16 @@ xfs_bmap_check_leaf_extents(
6285 */ 6284 */
6286 6285
6287 ep = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1); 6286 ep = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1);
6287 if (i) {
6288 xfs_btree_check_rec(XFS_BTNUM_BMAP, &last, ep);
6289 }
6288 for (j = 1; j < num_recs; j++) { 6290 for (j = 1; j < num_recs; j++) {
6289 nextp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, j + 1); 6291 nextp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, j + 1);
6290 if (lastp) { 6292 xfs_btree_check_rec(XFS_BTNUM_BMAP, ep, nextp);
6291 xfs_btree_check_rec(XFS_BTNUM_BMAP,
6292 (void *)lastp, (void *)ep);
6293 }
6294 xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep,
6295 (void *)(nextp));
6296 lastp = ep;
6297 ep = nextp; 6293 ep = nextp;
6298 } 6294 }
6299 6295
6296 last = *ep;
6300 i += num_recs; 6297 i += num_recs;
6301 if (bp_release) { 6298 if (bp_release) {
6302 bp_release = 0; 6299 bp_release = 0;