|
@@ -1462,70 +1462,95 @@ xfs_ialloc_log_agi(
|
|
|
xfs_trans_log_buf(tp, bp, first, last);
|
|
|
}
|
|
|
|
|
|
+#ifdef DEBUG
|
|
|
+STATIC void
|
|
|
+xfs_check_agi_unlinked(
|
|
|
+ struct xfs_agi *agi)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
|
|
|
+ ASSERT(agi->agi_unlinked[i]);
|
|
|
+}
|
|
|
+#else
|
|
|
+#define xfs_check_agi_unlinked(agi)
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* Read in the allocation group header (inode allocation section)
|
|
|
*/
|
|
|
int
|
|
|
-xfs_ialloc_read_agi(
|
|
|
- xfs_mount_t *mp, /* file system mount structure */
|
|
|
- xfs_trans_t *tp, /* transaction pointer */
|
|
|
- xfs_agnumber_t agno, /* allocation group number */
|
|
|
- xfs_buf_t **bpp) /* allocation group hdr buf */
|
|
|
+xfs_read_agi(
|
|
|
+ struct xfs_mount *mp, /* file system mount structure */
|
|
|
+ struct xfs_trans *tp, /* transaction pointer */
|
|
|
+ xfs_agnumber_t agno, /* allocation group number */
|
|
|
+ struct xfs_buf **bpp) /* allocation group hdr buf */
|
|
|
{
|
|
|
- xfs_agi_t *agi; /* allocation group header */
|
|
|
- int agi_ok; /* agi is consistent */
|
|
|
- xfs_buf_t *bp; /* allocation group hdr buf */
|
|
|
- xfs_perag_t *pag; /* per allocation group data */
|
|
|
- int error;
|
|
|
+ struct xfs_agi *agi; /* allocation group header */
|
|
|
+ int agi_ok; /* agi is consistent */
|
|
|
+ int error;
|
|
|
|
|
|
ASSERT(agno != NULLAGNUMBER);
|
|
|
- error = xfs_trans_read_buf(
|
|
|
- mp, tp, mp->m_ddev_targp,
|
|
|
+
|
|
|
+ error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
|
|
|
XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
|
|
|
- XFS_FSS_TO_BB(mp, 1), 0, &bp);
|
|
|
+ XFS_FSS_TO_BB(mp, 1), 0, bpp);
|
|
|
if (error)
|
|
|
return error;
|
|
|
- ASSERT(bp && !XFS_BUF_GETERROR(bp));
|
|
|
+
|
|
|
+ ASSERT(*bpp && !XFS_BUF_GETERROR(*bpp));
|
|
|
+ agi = XFS_BUF_TO_AGI(*bpp);
|
|
|
|
|
|
/*
|
|
|
* Validate the magic number of the agi block.
|
|
|
*/
|
|
|
- agi = XFS_BUF_TO_AGI(bp);
|
|
|
- agi_ok =
|
|
|
- be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC &&
|
|
|
- XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum));
|
|
|
+ agi_ok = be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC &&
|
|
|
+ XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)) &&
|
|
|
+ be32_to_cpu(agi->agi_seqno) == agno;
|
|
|
if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
|
|
|
XFS_RANDOM_IALLOC_READ_AGI))) {
|
|
|
- XFS_CORRUPTION_ERROR("xfs_ialloc_read_agi", XFS_ERRLEVEL_LOW,
|
|
|
+ XFS_CORRUPTION_ERROR("xfs_read_agi", XFS_ERRLEVEL_LOW,
|
|
|
mp, agi);
|
|
|
- xfs_trans_brelse(tp, bp);
|
|
|
+ xfs_trans_brelse(tp, *bpp);
|
|
|
return XFS_ERROR(EFSCORRUPTED);
|
|
|
}
|
|
|
+
|
|
|
+ XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_AGI, XFS_AGI_REF);
|
|
|
+
|
|
|
+ xfs_check_agi_unlinked(agi);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+xfs_ialloc_read_agi(
|
|
|
+ struct xfs_mount *mp, /* file system mount structure */
|
|
|
+ struct xfs_trans *tp, /* transaction pointer */
|
|
|
+ xfs_agnumber_t agno, /* allocation group number */
|
|
|
+ struct xfs_buf **bpp) /* allocation group hdr buf */
|
|
|
+{
|
|
|
+ struct xfs_agi *agi; /* allocation group header */
|
|
|
+ struct xfs_perag *pag; /* per allocation group data */
|
|
|
+ int error;
|
|
|
+
|
|
|
+ error = xfs_read_agi(mp, tp, agno, bpp);
|
|
|
+ if (error)
|
|
|
+ return error;
|
|
|
+
|
|
|
+ agi = XFS_BUF_TO_AGI(*bpp);
|
|
|
pag = &mp->m_perag[agno];
|
|
|
+
|
|
|
if (!pag->pagi_init) {
|
|
|
pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
|
|
|
pag->pagi_count = be32_to_cpu(agi->agi_count);
|
|
|
pag->pagi_init = 1;
|
|
|
- } else {
|
|
|
- /*
|
|
|
- * It's possible for these to be out of sync if
|
|
|
- * we are in the middle of a forced shutdown.
|
|
|
- */
|
|
|
- ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
|
|
|
- XFS_FORCED_SHUTDOWN(mp));
|
|
|
- }
|
|
|
-
|
|
|
-#ifdef DEBUG
|
|
|
- {
|
|
|
- int i;
|
|
|
-
|
|
|
- for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
|
|
|
- ASSERT(agi->agi_unlinked[i]);
|
|
|
}
|
|
|
-#endif
|
|
|
|
|
|
- XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGI, XFS_AGI_REF);
|
|
|
- *bpp = bp;
|
|
|
+ /*
|
|
|
+ * It's possible for these to be out of sync if
|
|
|
+ * we are in the middle of a forced shutdown.
|
|
|
+ */
|
|
|
+ ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
|
|
|
+ XFS_FORCED_SHUTDOWN(mp));
|
|
|
return 0;
|
|
|
}
|
|
|
|