diff options
author | From: Christoph Hellwig <hch@lst.de> | 2008-11-27 22:23:38 -0500 |
---|---|---|
committer | Niv Sardi <xaiki@sgi.com> | 2008-11-30 19:37:20 -0500 |
commit | 4805621a37d9b2b16641b5c68597651419e9e252 (patch) | |
tree | a3c63689100a8c7ca2eb72efe4036f7863c34e12 /fs | |
parent | 5e1be0fb1a3950597aeda448698e85b0595a2e92 (diff) |
[XFS] factor out xfs_read_agf helper
Add a helper to read the AGF 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')
-rw-r--r-- | fs/xfs/xfs_ag.h | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_alloc.c | 69 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 26 |
3 files changed, 61 insertions, 36 deletions
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index f4a315390c61..f2e21817a226 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h | |||
@@ -91,6 +91,8 @@ typedef struct xfs_agf { | |||
91 | #define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp)) | 91 | #define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp)) |
92 | #define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp)) | 92 | #define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp)) |
93 | 93 | ||
94 | extern int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, | ||
95 | xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); | ||
94 | 96 | ||
95 | /* | 97 | /* |
96 | * Size of the unlinked inode hash table in the agi. | 98 | * Size of the unlinked inode hash table in the agi. |
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index c47ce9075728..028e44e58ea9 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c | |||
@@ -2233,44 +2233,41 @@ xfs_alloc_put_freelist( | |||
2233 | * Read in the allocation group header (free/alloc section). | 2233 | * Read in the allocation group header (free/alloc section). |
2234 | */ | 2234 | */ |
2235 | int /* error */ | 2235 | int /* error */ |
2236 | xfs_alloc_read_agf( | 2236 | xfs_read_agf( |
2237 | xfs_mount_t *mp, /* mount point structure */ | 2237 | struct xfs_mount *mp, /* mount point structure */ |
2238 | xfs_trans_t *tp, /* transaction pointer */ | 2238 | struct xfs_trans *tp, /* transaction pointer */ |
2239 | xfs_agnumber_t agno, /* allocation group number */ | 2239 | xfs_agnumber_t agno, /* allocation group number */ |
2240 | int flags, /* XFS_ALLOC_FLAG_... */ | 2240 | int flags, /* XFS_BUF_ */ |
2241 | xfs_buf_t **bpp) /* buffer for the ag freelist header */ | 2241 | struct xfs_buf **bpp) /* buffer for the ag freelist header */ |
2242 | { | 2242 | { |
2243 | xfs_agf_t *agf; /* ag freelist header */ | 2243 | struct xfs_agf *agf; /* ag freelist header */ |
2244 | int agf_ok; /* set if agf is consistent */ | 2244 | int agf_ok; /* set if agf is consistent */ |
2245 | xfs_buf_t *bp; /* return value */ | ||
2246 | xfs_perag_t *pag; /* per allocation group data */ | ||
2247 | int error; | 2245 | int error; |
2248 | 2246 | ||
2249 | ASSERT(agno != NULLAGNUMBER); | 2247 | ASSERT(agno != NULLAGNUMBER); |
2250 | error = xfs_trans_read_buf( | 2248 | error = xfs_trans_read_buf( |
2251 | mp, tp, mp->m_ddev_targp, | 2249 | mp, tp, mp->m_ddev_targp, |
2252 | XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), | 2250 | XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)), |
2253 | XFS_FSS_TO_BB(mp, 1), | 2251 | XFS_FSS_TO_BB(mp, 1), flags, bpp); |
2254 | (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XFS_BUF_TRYLOCK : 0U, | ||
2255 | &bp); | ||
2256 | if (error) | 2252 | if (error) |
2257 | return error; | 2253 | return error; |
2258 | ASSERT(!bp || !XFS_BUF_GETERROR(bp)); | 2254 | if (!*bpp) |
2259 | if (!bp) { | ||
2260 | *bpp = NULL; | ||
2261 | return 0; | 2255 | return 0; |
2262 | } | 2256 | |
2257 | ASSERT(!XFS_BUF_GETERROR(*bpp)); | ||
2258 | agf = XFS_BUF_TO_AGF(*bpp); | ||
2259 | |||
2263 | /* | 2260 | /* |
2264 | * Validate the magic number of the agf block. | 2261 | * Validate the magic number of the agf block. |
2265 | */ | 2262 | */ |
2266 | agf = XFS_BUF_TO_AGF(bp); | ||
2267 | agf_ok = | 2263 | agf_ok = |
2268 | be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC && | 2264 | be32_to_cpu(agf->agf_magicnum) == XFS_AGF_MAGIC && |
2269 | XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && | 2265 | XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && |
2270 | be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && | 2266 | be32_to_cpu(agf->agf_freeblks) <= be32_to_cpu(agf->agf_length) && |
2271 | be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) && | 2267 | be32_to_cpu(agf->agf_flfirst) < XFS_AGFL_SIZE(mp) && |
2272 | be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) && | 2268 | be32_to_cpu(agf->agf_fllast) < XFS_AGFL_SIZE(mp) && |
2273 | be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp); | 2269 | be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp) && |
2270 | be32_to_cpu(agf->agf_seqno) == agno; | ||
2274 | if (xfs_sb_version_haslazysbcount(&mp->m_sb)) | 2271 | if (xfs_sb_version_haslazysbcount(&mp->m_sb)) |
2275 | agf_ok = agf_ok && be32_to_cpu(agf->agf_btreeblks) <= | 2272 | agf_ok = agf_ok && be32_to_cpu(agf->agf_btreeblks) <= |
2276 | be32_to_cpu(agf->agf_length); | 2273 | be32_to_cpu(agf->agf_length); |
@@ -2278,9 +2275,41 @@ xfs_alloc_read_agf( | |||
2278 | XFS_RANDOM_ALLOC_READ_AGF))) { | 2275 | XFS_RANDOM_ALLOC_READ_AGF))) { |
2279 | XFS_CORRUPTION_ERROR("xfs_alloc_read_agf", | 2276 | XFS_CORRUPTION_ERROR("xfs_alloc_read_agf", |
2280 | XFS_ERRLEVEL_LOW, mp, agf); | 2277 | XFS_ERRLEVEL_LOW, mp, agf); |
2281 | xfs_trans_brelse(tp, bp); | 2278 | xfs_trans_brelse(tp, *bpp); |
2282 | return XFS_ERROR(EFSCORRUPTED); | 2279 | return XFS_ERROR(EFSCORRUPTED); |
2283 | } | 2280 | } |
2281 | |||
2282 | XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGF, XFS_AGF_REF); | ||
2283 | return 0; | ||
2284 | } | ||
2285 | |||
2286 | /* | ||
2287 | * Read in the allocation group header (free/alloc section). | ||
2288 | */ | ||
2289 | int /* error */ | ||
2290 | xfs_alloc_read_agf( | ||
2291 | struct xfs_mount *mp, /* mount point structure */ | ||
2292 | struct xfs_trans *tp, /* transaction pointer */ | ||
2293 | xfs_agnumber_t agno, /* allocation group number */ | ||
2294 | int flags, /* XFS_ALLOC_FLAG_... */ | ||
2295 | struct xfs_buf **bpp) /* buffer for the ag freelist header */ | ||
2296 | { | ||
2297 | struct xfs_agf *agf; /* ag freelist header */ | ||
2298 | struct xfs_perag *pag; /* per allocation group data */ | ||
2299 | int error; | ||
2300 | |||
2301 | ASSERT(agno != NULLAGNUMBER); | ||
2302 | |||
2303 | error = xfs_read_agf(mp, tp, agno, | ||
2304 | (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XFS_BUF_TRYLOCK : 0, | ||
2305 | bpp); | ||
2306 | if (error) | ||
2307 | return error; | ||
2308 | if (!*bpp) | ||
2309 | return 0; | ||
2310 | ASSERT(!XFS_BUF_GETERROR(*bpp)); | ||
2311 | |||
2312 | agf = XFS_BUF_TO_AGF(*bpp); | ||
2284 | pag = &mp->m_perag[agno]; | 2313 | pag = &mp->m_perag[agno]; |
2285 | if (!pag->pagf_init) { | 2314 | if (!pag->pagf_init) { |
2286 | pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); | 2315 | pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks); |
@@ -2308,8 +2337,6 @@ xfs_alloc_read_agf( | |||
2308 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); | 2337 | be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi])); |
2309 | } | 2338 | } |
2310 | #endif | 2339 | #endif |
2311 | XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGF, XFS_AGF_REF); | ||
2312 | *bpp = bp; | ||
2313 | return 0; | 2340 | return 0; |
2314 | } | 2341 | } |
2315 | 2342 | ||
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index b552676ca5c4..d94987915d5e 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -3970,7 +3970,6 @@ xlog_recover_check_summary( | |||
3970 | xfs_agf_t *agfp; | 3970 | xfs_agf_t *agfp; |
3971 | xfs_buf_t *agfbp; | 3971 | xfs_buf_t *agfbp; |
3972 | xfs_buf_t *agibp; | 3972 | xfs_buf_t *agibp; |
3973 | xfs_daddr_t agfdaddr; | ||
3974 | xfs_buf_t *sbbp; | 3973 | xfs_buf_t *sbbp; |
3975 | #ifdef XFS_LOUD_RECOVERY | 3974 | #ifdef XFS_LOUD_RECOVERY |
3976 | xfs_sb_t *sbp; | 3975 | xfs_sb_t *sbp; |
@@ -3987,21 +3986,18 @@ xlog_recover_check_summary( | |||
3987 | itotal = 0LL; | 3986 | itotal = 0LL; |
3988 | ifree = 0LL; | 3987 | ifree = 0LL; |
3989 | for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { | 3988 | for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) { |
3990 | agfdaddr = XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)); | 3989 | error = xfs_read_agf(mp, NULL, agno, 0, &agfbp); |
3991 | agfbp = xfs_buf_read(mp->m_ddev_targp, agfdaddr, | 3990 | if (error) { |
3992 | XFS_FSS_TO_BB(mp, 1), 0); | 3991 | xfs_fs_cmn_err(CE_ALERT, mp, |
3993 | if (XFS_BUF_ISERROR(agfbp)) { | 3992 | "xlog_recover_check_summary(agf)" |
3994 | xfs_ioerror_alert("xlog_recover_check_summary(agf)", | 3993 | "agf read failed agno %d error %d", |
3995 | mp, agfbp, agfdaddr); | 3994 | agno, error); |
3995 | } else { | ||
3996 | agfp = XFS_BUF_TO_AGF(agfbp); | ||
3997 | freeblks += be32_to_cpu(agfp->agf_freeblks) + | ||
3998 | be32_to_cpu(agfp->agf_flcount); | ||
3999 | xfs_buf_relse(agfbp); | ||
3996 | } | 4000 | } |
3997 | agfp = XFS_BUF_TO_AGF(agfbp); | ||
3998 | ASSERT(XFS_AGF_MAGIC == be32_to_cpu(agfp->agf_magicnum)); | ||
3999 | ASSERT(XFS_AGF_GOOD_VERSION(be32_to_cpu(agfp->agf_versionnum))); | ||
4000 | ASSERT(be32_to_cpu(agfp->agf_seqno) == agno); | ||
4001 | |||
4002 | freeblks += be32_to_cpu(agfp->agf_freeblks) + | ||
4003 | be32_to_cpu(agfp->agf_flcount); | ||
4004 | xfs_buf_relse(agfbp); | ||
4005 | 4001 | ||
4006 | error = xfs_read_agi(mp, NULL, agno, &agibp); | 4002 | error = xfs_read_agi(mp, NULL, agno, &agibp); |
4007 | if (!error) { | 4003 | if (!error) { |