pop_cur();
}
+struct agfl_state {
+ xfs_agnumber_t agno;
+ unsigned int count;
+};
+
+static int
+scan_agfl(
+ struct xfs_mount *mp,
+ xfs_agblock_t bno,
+ void *priv)
+{
+ struct agfl_state *as = priv;
+
+ set_dbmap(as->agno, bno, 1, DBM_FREELIST, as->agno, XFS_AGFL_BLOCK(mp));
+ as->count++;
+ return 0;
+}
+
static void
scan_freelist(
- xfs_agf_t *agf)
+ xfs_agf_t *agf)
{
- xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno);
- xfs_agfl_t *agfl;
- xfs_agblock_t bno;
- uint count;
- int i;
- __be32 *freelist;
+ xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno);
+ struct agfl_state state;
if (XFS_SB_BLOCK(mp) != XFS_AGFL_BLOCK(mp) &&
XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) &&
set_cur(&typtab[TYP_AGFL],
XFS_AG_DADDR(mp, seqno, XFS_AGFL_DADDR(mp)),
XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL);
- if ((agfl = iocur_top->data) == NULL) {
+ if (iocur_top->data == NULL) {
dbprintf(_("can't read agfl block for ag %u\n"), seqno);
serious_error++;
pop_cur();
return;
}
- i = be32_to_cpu(agf->agf_flfirst);
/* verify agf values before proceeding */
if (be32_to_cpu(agf->agf_flfirst) >= libxfs_agfl_size(mp) ||
be32_to_cpu(agf->agf_fllast) >= libxfs_agfl_size(mp)) {
dbprintf(_("agf %d freelist blocks bad, skipping "
- "freelist scan\n"), i);
+ "freelist scan\n"), seqno);
pop_cur();
return;
}
/* open coded XFS_BUF_TO_AGFL_BNO */
- freelist = xfs_sb_version_hascrc(&((mp)->m_sb)) ? &agfl->agfl_bno[0]
- : (__be32 *)agfl;
- count = 0;
- for (;;) {
- bno = be32_to_cpu(freelist[i]);
- set_dbmap(seqno, bno, 1, DBM_FREELIST, seqno,
- XFS_AGFL_BLOCK(mp));
- count++;
- if (i == be32_to_cpu(agf->agf_fllast))
- break;
- if (++i == libxfs_agfl_size(mp))
- i = 0;
- }
- if (count != be32_to_cpu(agf->agf_flcount)) {
+ state.count = 0;
+ state.agno = seqno;
+ libxfs_agfl_walk(mp, agf, iocur_top->bp, scan_agfl, &state);
+ if (state.count != be32_to_cpu(agf->agf_flcount)) {
if (!sflag)
dbprintf(_("freeblk count %u != flcount %u in ag %u\n"),
- count, be32_to_cpu(agf->agf_flcount),
- seqno);
+ state.count,
+ be32_to_cpu(agf->agf_flcount),
+ seqno);
error++;
}
- fdblocks += count;
- agf_aggr_freeblks += count;
+ fdblocks += state.count;
+ agf_aggr_freeblks += state.count;
pop_cur();
}
pop_cur();
}
+static int
+scan_agfl(
+ struct xfs_mount *mp,
+ xfs_agblock_t bno,
+ void *priv)
+{
+ addtohist(*(xfs_agnumber_t *)priv, bno, 1);
+ return 0;
+}
+
static void
scan_freelist(
xfs_agf_t *agf)
{
xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno);
- xfs_agfl_t *agfl;
- xfs_agblock_t bno;
- int i;
- __be32 *agfl_bno;
if (be32_to_cpu(agf->agf_flcount) == 0)
return;
push_cur();
set_cur(&typtab[TYP_AGFL], XFS_AG_DADDR(mp, seqno, XFS_AGFL_DADDR(mp)),
XFS_FSS_TO_BB(mp, 1), DB_RING_IGN, NULL);
- agfl = iocur_top->data;
- i = be32_to_cpu(agf->agf_flfirst);
-
- /* open coded XFS_BUF_TO_AGFL_BNO */
- agfl_bno = xfs_sb_version_hascrc(&mp->m_sb) ? &agfl->agfl_bno[0]
- : (__be32 *)agfl;
/* verify agf values before proceeding */
if (be32_to_cpu(agf->agf_flfirst) >= libxfs_agfl_size(mp) ||
be32_to_cpu(agf->agf_fllast) >= libxfs_agfl_size(mp)) {
dbprintf(_("agf %d freelist blocks bad, skipping "
- "freelist scan\n"), i);
+ "freelist scan\n"), seqno);
pop_cur();
return;
}
- for (;;) {
- bno = be32_to_cpu(agfl_bno[i]);
- addtohist(seqno, bno, 1);
- if (i == be32_to_cpu(agf->agf_fllast))
- break;
- if (++i == libxfs_agfl_size(mp))
- i = 0;
- }
+ libxfs_agfl_walk(mp, agf, iocur_top->bp, scan_agfl, &seqno);
pop_cur();
}
#define xfs_attr_remove libxfs_attr_remove
#define xfs_attr_leaf_newentsize libxfs_attr_leaf_newentsize
+#define xfs_agfl_walk libxfs_agfl_walk
#define xfs_alloc_fix_freelist libxfs_alloc_fix_freelist
#define xfs_alloc_min_freelist libxfs_alloc_min_freelist
#define xfs_alloc_read_agf libxfs_alloc_read_agf
}
}
+struct agfl_state {
+ unsigned int count;
+ xfs_agnumber_t agno;
+};
+
+static int
+scan_agfl(
+ struct xfs_mount *mp,
+ xfs_agblock_t bno,
+ void *priv)
+{
+ struct agfl_state *as = priv;
+
+ if (verify_agbno(mp, as->agno, bno))
+ set_bmap(as->agno, bno, XR_E_FREE);
+ else
+ do_warn(_("bad agbno %u in agfl, agno %d\n"),
+ bno, as->agno);
+ as->count++;
+ return 0;
+}
+
static void
scan_freelist(
- xfs_agf_t *agf,
- struct aghdr_cnts *agcnts)
+ xfs_agf_t *agf,
+ struct aghdr_cnts *agcnts)
{
- xfs_buf_t *agflbuf;
- xfs_agnumber_t agno;
- xfs_agblock_t bno;
- int count;
- int i;
- __be32 *freelist;
+ xfs_buf_t *agflbuf;
+ xfs_agnumber_t agno;
+ struct agfl_state state;
agno = be32_to_cpu(agf->agf_seqno);
if (agflbuf->b_error == -EFSBADCRC)
do_warn(_("agfl has bad CRC for ag %d\n"), agno);
- freelist = XFS_BUF_TO_AGFL_BNO(mp, agflbuf);
- i = be32_to_cpu(agf->agf_flfirst);
-
if (no_modify) {
/* agf values not fixed in verify_set_agf, so recheck */
if (be32_to_cpu(agf->agf_flfirst) >= libxfs_agfl_size(mp) ||
be32_to_cpu(agf->agf_fllast) >= libxfs_agfl_size(mp)) {
do_warn(_("agf %d freelist blocks bad, skipping "
- "freelist scan\n"), i);
+ "freelist scan\n"), agno);
return;
}
}
- count = 0;
- for (;;) {
- bno = be32_to_cpu(freelist[i]);
- if (verify_agbno(mp, agno, bno))
- set_bmap(agno, bno, XR_E_FREE);
- else
- do_warn(_("bad agbno %u in agfl, agno %d\n"),
- bno, agno);
- count++;
- if (i == be32_to_cpu(agf->agf_fllast))
- break;
- if (++i == libxfs_agfl_size(mp))
- i = 0;
- }
- if (count != be32_to_cpu(agf->agf_flcount)) {
- do_warn(_("freeblk count %d != flcount %d in ag %d\n"), count,
- be32_to_cpu(agf->agf_flcount), agno);
+ state.count = 0;
+ state.agno = agno;
+ libxfs_agfl_walk(mp, agf, agflbuf, scan_agfl, &state);
+ if (state.count != be32_to_cpu(agf->agf_flcount)) {
+ do_warn(_("freeblk count %d != flcount %d in ag %d\n"),
+ state.count, be32_to_cpu(agf->agf_flcount),
+ agno);
}
- agcnts->fdblocks += count;
+ agcnts->fdblocks += state.count;
libxfs_putbuf(agflbuf);
}