[PATCH 07/19] xfs: verify AGFL blocks as they are read from disk

Dave Chinner
2012-10-09T03:50:07Z

Add an AGFL block verify callback function and pass it into the
buffer read functions. Add a debug only check for valid block
numbers in the AGFL.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/xfs_alloc.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index bd565a2..75c5d82 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -430,6 +430,29 @@ xfs_alloc_fixup_trees(
return 0;
}

+void
+xfs_agfl_read_verify(
+ struct xfs_buf *bp)
+{
+ struct xfs_mount *mp = bp->b_target->bt_mount;
+ struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(bp);
+ int agfl_ok = 1;
+ int i;
+
+ for (i = 0; i < XFS_AGFL_SIZE(mp); i++) {
+ if (agfl->agfl_bno[i] == 0)
+ agfl = 0;
+ }
+
+ if (!agfl_ok) {
+ XFS_CORRUPTION_ERROR("xfs_agfl_read_verify",
+ XFS_ERRLEVEL_LOW, mp, agfl);
+ xfs_buf_ioerror(bp, EFSCORRUPTED);
+ }
+ bp->b_iodone = NULL;
+ xfs_buf_ioend(bp, 0);
+}
+
/*
* Read in the allocation group free block array.
*/
@@ -447,7 +470,7 @@ xfs_alloc_read_agfl(
error = xfs_trans_read_buf(
mp, tp, mp->m_ddev_targp,
XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)),
- XFS_FSS_TO_BB(mp, 1), 0, &bp, NULL);
+ XFS_FSS_TO_BB(mp, 1), 0, &bp, xfs_agfl_read_verify);
if (error)
return error;
ASSERT(!xfs_buf_geterror(bp));