aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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
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')
-rw-r--r--fs/xfs/xfs_ag.h2
-rw-r--r--fs/xfs/xfs_alloc.c69
-rw-r--r--fs/xfs/xfs_log_recover.c26
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
94extern 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 */
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
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) {