aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_alloc.c
diff options
context:
space:
mode:
authorFrom: Christoph Hellwig <hch@lst.de>2008-11-27 22:23:38 -0500
committerNiv Sardi <xaiki@sgi.com>2008-11-30 19:37:20 -0500
commit4805621a37d9b2b16641b5c68597651419e9e252 (patch)
treea3c63689100a8c7ca2eb72efe4036f7863c34e12 /fs/xfs/xfs_alloc.c
parent5e1be0fb1a3950597aeda448698e85b0595a2e92 (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.c69
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 */
2235int /* error */ 2235int /* error */
2236xfs_alloc_read_agf( 2236xfs_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 */
2289int /* error */
2290xfs_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