aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@sgi.com>2008-03-27 18:01:14 +1100
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-04-18 11:49:51 +1000
commit2abdb8c88110bab78bfe17e51346e735560daa02 (patch)
tree0fad752a8f931991f0a788d52aeaaee508c0c3ea
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>
-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 bce8e3bd8ad..7d683e0b8ef 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -6194,7 +6194,7 @@ xfs_bmap_check_leaf_extents(
xfs_mount_t *mp; /* file system mount structure */
__be64 *pp; /* pointer to block address */
xfs_bmbt_rec_t *ep; /* pointer to current extent */
- xfs_bmbt_rec_t *lastp; /* pointer to previous extent */
+ xfs_bmbt_rec_t last = {0, 0}; /* last extent in prev block */
xfs_bmbt_rec_t *nextp; /* pointer to next extent */
int bp_release = 0;
@@ -6264,7 +6264,6 @@ xfs_bmap_check_leaf_extents(
/*
* Loop over all leaf nodes checking that all extents are in the right order.
*/
- lastp = NULL;
for (;;) {
xfs_fsblock_t nextbno;
xfs_extnum_t num_recs;
@@ -6285,18 +6284,16 @@ xfs_bmap_check_leaf_extents(
*/
ep = XFS_BTREE_REC_ADDR(xfs_bmbt, block, 1);
+ if (i) {
+ xfs_btree_check_rec(XFS_BTNUM_BMAP, &last, ep);
+ }
for (j = 1; j < num_recs; j++) {
nextp = XFS_BTREE_REC_ADDR(xfs_bmbt, block, j + 1);
- if (lastp) {
- xfs_btree_check_rec(XFS_BTNUM_BMAP,
- (void *)lastp, (void *)ep);
- }
- xfs_btree_check_rec(XFS_BTNUM_BMAP, (void *)ep,
- (void *)(nextp));
- lastp = ep;
+ xfs_btree_check_rec(XFS_BTNUM_BMAP, ep, nextp);
ep = nextp;
}
+ last = *ep;
i += num_recs;
if (bp_release) {
bp_release = 0;