aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log_recover.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2008-11-27 22:23:37 -0500
committerNiv Sardi <xaiki@sgi.com>2008-11-30 19:37:15 -0500
commit5e1be0fb1a3950597aeda448698e85b0595a2e92 (patch)
treee9cb423d6f253b689a9e0cfb4a1d429de37959cd /fs/xfs/xfs_log_recover.c
parent26c5295135d10fc90cbf160adfda392d91f58279 (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.c72
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);