diff options
author | Christoph Hellwig <hch@lst.de> | 2008-11-27 22:23:37 -0500 |
---|---|---|
committer | Niv Sardi <xaiki@sgi.com> | 2008-11-30 19:37:15 -0500 |
commit | 5e1be0fb1a3950597aeda448698e85b0595a2e92 (patch) | |
tree | e9cb423d6f253b689a9e0cfb4a1d429de37959cd /fs/xfs/xfs_log_recover.c | |
parent | 26c5295135d10fc90cbf160adfda392d91f58279 (diff) |
[XFS] factor out xfs_read_agi helper
Add a helper to read the AGI header and perform basic verification.
Based on hunks from a larger patch from Dave Chinner.
(First sent on Juli 23rd)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Niv Sardi <xaiki@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_log_recover.c')
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 72 |
1 files changed, 26 insertions, 46 deletions
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b411d4947318..b552676ca5c4 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -3117,19 +3117,16 @@ xlog_recover_clear_agi_bucket( | |||
3117 | int error; | 3117 | int error; |
3118 | 3118 | ||
3119 | tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET); | 3119 | tp = xfs_trans_alloc(mp, XFS_TRANS_CLEAR_AGI_BUCKET); |
3120 | error = xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), 0, 0, 0); | 3120 | error = xfs_trans_reserve(tp, 0, XFS_CLEAR_AGI_BUCKET_LOG_RES(mp), |
3121 | if (!error) | 3121 | 0, 0, 0); |
3122 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, | ||
3123 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), | ||
3124 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); | ||
3125 | if (error) | 3122 | if (error) |
3126 | goto out_abort; | 3123 | goto out_abort; |
3127 | 3124 | ||
3128 | error = EINVAL; | 3125 | error = xfs_read_agi(mp, tp, agno, &agibp); |
3129 | agi = XFS_BUF_TO_AGI(agibp); | 3126 | if (error) |
3130 | if (be32_to_cpu(agi->agi_magicnum) != XFS_AGI_MAGIC) | ||
3131 | goto out_abort; | 3127 | goto out_abort; |
3132 | 3128 | ||
3129 | agi = XFS_BUF_TO_AGI(agibp); | ||
3133 | agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO); | 3130 | agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO); |
3134 | offset = offsetof(xfs_agi_t, agi_unlinked) + | 3131 | offset = offsetof(xfs_agi_t, agi_unlinked) + |
3135 | (sizeof(xfs_agino_t) * bucket); | 3132 | (sizeof(xfs_agino_t) * bucket); |
@@ -3190,16 +3187,17 @@ xlog_recover_process_iunlinks( | |||
3190 | /* | 3187 | /* |
3191 | * Find the agi for this ag. | 3188 | * Find the agi for this ag. |
3192 | */ | 3189 | */ |
3193 | agibp = xfs_buf_read(mp->m_ddev_targp, | 3190 | error = xfs_read_agi(mp, NULL, agno, &agibp); |
3194 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)), | 3191 | if (error) { |
3195 | XFS_FSS_TO_BB(mp, 1), 0); | 3192 | /* |
3196 | if (XFS_BUF_ISERROR(agibp)) { | 3193 | * AGI is b0rked. Don't process it. |
3197 | xfs_ioerror_alert("xlog_recover_process_iunlinks(#1)", | 3194 | * |
3198 | log->l_mp, agibp, | 3195 | * We should probably mark the filesystem as corrupt |
3199 | XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp))); | 3196 | * after we've recovered all the ag's we can.... |
3197 | */ | ||
3198 | continue; | ||
3200 | } | 3199 | } |
3201 | agi = XFS_BUF_TO_AGI(agibp); | 3200 | agi = XFS_BUF_TO_AGI(agibp); |
3202 | ASSERT(XFS_AGI_MAGIC == be32_to_cpu(agi->agi_magicnum)); | ||
3203 | 3201 | ||
3204 | for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) { | 3202 | for (bucket = 0; bucket < XFS_AGI_UNLINKED_BUCKETS; bucket++) { |
3205 | 3203 | ||
@@ -3278,22 +3276,12 @@ xlog_recover_process_iunlinks( | |||
3278 | 3276 | ||
3279 | /* | 3277 | /* |
3280 | * Reacquire the agibuffer and continue around | 3278 | * Reacquire the agibuffer and continue around |
3281 | * the loop. | 3279 | * the loop. This should never fail as we know |
3280 | * the buffer was good earlier on. | ||
3282 | */ | 3281 | */ |
3283 | agibp = xfs_buf_read(mp->m_ddev_targp, | 3282 | error = xfs_read_agi(mp, NULL, agno, &agibp); |
3284 | XFS_AG_DADDR(mp, agno, | 3283 | ASSERT(error == 0); |
3285 | XFS_AGI_DADDR(mp)), | ||
3286 | XFS_FSS_TO_BB(mp, 1), 0); | ||
3287 | if (XFS_BUF_ISERROR(agibp)) { | ||
3288 | xfs_ioerror_alert( | ||
3289 | "xlog_recover_process_iunlinks(#2)", | ||
3290 | log->l_mp, agibp, | ||
3291 | XFS_AG_DADDR(mp, agno, | ||
3292 | XFS_AGI_DADDR(mp))); | ||
3293 | } | ||
3294 | agi = XFS_BUF_TO_AGI(agibp); | 3284 | agi = XFS_BUF_TO_AGI(agibp); |
3295 | ASSERT(XFS_AGI_MAGIC == be32_to_cpu( | ||
3296 | agi->agi_magicnum)); | ||
3297 | } | 3285 | } |
3298 | } | 3286 | } |
3299 | 3287 | ||
@@ -3980,11 +3968,9 @@ xlog_recover_check_summary( | |||
3980 | { | 3968 | { |
3981 | xfs_mount_t *mp; | 3969 | xfs_mount_t *mp; |
3982 | xfs_agf_t *agfp; | 3970 | xfs_agf_t *agfp; |
3983 | xfs_agi_t *agip; | ||
3984 | xfs_buf_t *agfbp; | 3971 | xfs_buf_t *agfbp; |
3985 | xfs_buf_t *agibp; | 3972 | xfs_buf_t *agibp; |
3986 | xfs_daddr_t agfdaddr; | 3973 | xfs_daddr_t agfdaddr; |
3987 | xfs_daddr_t agidaddr; | ||
3988 | xfs_buf_t *sbbp; | 3974 | xfs_buf_t *sbbp; |
3989 | #ifdef XFS_LOUD_RECOVERY | 3975 | #ifdef XFS_LOUD_RECOVERY |
3990 | xfs_sb_t *sbp; | 3976 | xfs_sb_t *sbp; |
@@ -3993,6 +3979,7 @@ xlog_recover_check_summary( | |||
3993 | __uint64_t freeblks; | 3979 | __uint64_t freeblks; |
3994 | __uint64_t itotal; | 3980 | __uint64_t itotal; |
3995 | __uint64_t ifree; | 3981 | __uint64_t ifree; |
3982 | int error; | ||
3996 | 3983 | ||
3997 | mp = log->l_mp; | 3984 | mp = log->l_mp; |
3998 | 3985 | ||
@@ -4016,21 +4003,14 @@ xlog_recover_check_summary( | |||
4016 | be32_to_cpu(agfp->agf_flcount); | 4003 | be32_to_cpu(agfp->agf_flcount); |
4017 | xfs_buf_relse(agfbp); | 4004 | xfs_buf_relse(agfbp); |
4018 | 4005 | ||
4019 | agidaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)); | 4006 | error = xfs_read_agi(mp, NULL, agno, &agibp); |
4020 | agibp = xfs_buf_read(mp->m_ddev_targp, agidaddr, | 4007 | if (!error) { |
4021 | XFS_FSS_TO_BB(mp, 1), 0); | 4008 | struct xfs_agi *agi = XFS_BUF_TO_AGI(agibp); |
4022 | if (XFS_BUF_ISERROR(agibp)) { | ||
4023 | xfs_ioerror_alert("xlog_recover_check_summary(agi)", | ||
4024 | mp, agibp, agidaddr); | ||
4025 | } | ||
4026 | agip = XFS_BUF_TO_AGI(agibp); | ||
4027 | ASSERT(XFS_AGI_MAGIC == be32_to_cpu(agip->agi_magicnum)); | ||
4028 | ASSERT(XFS_AGI_GOOD_VERSION(be32_to_cpu(agip->agi_versionnum))); | ||
4029 | ASSERT(be32_to_cpu(agip->agi_seqno) == agno); | ||
4030 | 4009 | ||
4031 | itotal += be32_to_cpu(agip->agi_count); | 4010 | itotal += be32_to_cpu(agi->agi_count); |
4032 | ifree += be32_to_cpu(agip->agi_freecount); | 4011 | ifree += be32_to_cpu(agi->agi_freecount); |
4033 | xfs_buf_relse(agibp); | 4012 | xfs_buf_relse(agibp); |
4013 | } | ||
4034 | } | 4014 | } |
4035 | 4015 | ||
4036 | sbbp = xfs_getsb(mp, 0); | 4016 | sbbp = xfs_getsb(mp, 0); |