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/xfs/xfs_alloc.c | |
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/xfs/xfs_alloc.c')
-rw-r--r-- | fs/xfs/xfs_alloc.c | 69 |
1 files changed, 48 insertions, 21 deletions
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 | ||