@@ -2220,66 +2220,62 @@ out_no_agbp:
* Get a block from the freelist.
* Returns with the buffer for the block gotten.
*/
-int /* error */
+int
xfs_alloc_get_freelist(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *agbp, /* buffer containing the agf structure */
- xfs_agblock_t *bnop, /* block address retrieved from freelist */
+ struct xfs_trans *tp,
+ struct xfs_buf *agbp,
+ xfs_agblock_t *bnop,
int btreeblk) /* destination is a AGF btree */
{
- xfs_agf_t *agf; /* a.g. freespace structure */
- xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */
- xfs_agblock_t bno; /* block number returned */
+ struct xfs_mount *mp = tp->t_mountp;
+ struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
+ struct xfs_buf *agflbp;
+ struct xfs_perag *pag;
+ xfs_agnumber_t agno = be32_to_cpu(agf->agf_seqno);
+ xfs_agblock_t bno = NULLAGBLOCK;
__be32 *agfl_bno;
int error;
int logflags;
- xfs_mount_t *mp = tp->t_mountp;
- xfs_perag_t *pag; /* per allocation group data */
- /*
- * Freelist is empty, give up.
- */
- agf = XFS_BUF_TO_AGF(agbp);
- if (!agf->agf_flcount) {
- *bnop = NULLAGBLOCK;
- return 0;
- }
+ /* Freelist is empty, give up. */
+ pag = xfs_perag_get(mp, agno);
+ if (!pag->pagf_flcount)
+ goto out_put_perag;
+
/*
* Read the array of free blocks.
*/
- error = xfs_alloc_read_agfl(mp, tp, be32_to_cpu(agf->agf_seqno),
- &agflbp);
+ error = xfs_alloc_read_agfl(mp, tp, agno, &agflbp);
if (error)
return error;
+ agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
+ logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
/*
* Get the block number and update the data structures.
*/
- agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
- bno = be32_to_cpu(agfl_bno[be32_to_cpu(agf->agf_flfirst)]);
- be32_add_cpu(&agf->agf_flfirst, 1);
- xfs_trans_brelse(tp, agflbp);
- if (be32_to_cpu(agf->agf_flfirst) == xfs_agfl_size(mp))
- agf->agf_flfirst = 0;
-
- pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
- be32_add_cpu(&agf->agf_flcount, -1);
- xfs_trans_agflist_delta(tp, -1);
+ bno = be32_to_cpu(agfl_bno[pag->pagf_flfirst]);
+ if (++pag->pagf_flfirst == xfs_agfl_size(mp))
+ pag->pagf_flfirst = 0;
pag->pagf_flcount--;
- pag->pagf_flfirst = be32_to_cpu(agf->agf_flfirst);
- xfs_perag_put(pag);
+ xfs_trans_agflist_delta(tp, -1);
- logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
if (btreeblk) {
- be32_add_cpu(&agf->agf_btreeblks, 1);
pag->pagf_btreeblks++;
+ agf->agf_btreeblks = cpu_to_be32(pag->pagf_btreeblks);
logflags |= XFS_AGF_BTREEBLKS;
}
+ agf->agf_flfirst = cpu_to_be32(pag->pagf_flfirst);
+ agf->agf_flcount = cpu_to_be32(pag->pagf_flcount);
+
+ xfs_trans_brelse(tp, agflbp);
xfs_alloc_log_agf(tp, agbp, logflags);
- *bnop = bno;
+out_put_perag:
+ xfs_perag_put(pag);
+ *bnop = bno;
return 0;
}
@@ -2345,53 +2341,51 @@ xfs_alloc_pagf_init(
/*
* Put the block on the freelist for the allocation group.
*/
-int /* error */
+int
xfs_alloc_put_freelist(
- xfs_trans_t *tp, /* transaction pointer */
- xfs_buf_t *agbp, /* buffer for a.g. freelist header */
- xfs_buf_t *agflbp,/* buffer for a.g. free block array */
- xfs_agblock_t bno, /* block being freed */
+ struct xfs_trans *tp,
+ struct xfs_buf *agbp,
+ struct xfs_buf *agflbp,
+ xfs_agblock_t bno,
int btreeblk) /* block came from a AGF btree */
{
- xfs_agf_t *agf; /* a.g. freespace structure */
- __be32 *blockp;/* pointer to array entry */
+ struct xfs_mount *mp = tp->t_mountp;
+ struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp);
+ struct xfs_perag *pag;
+ xfs_agnumber_t agno = be32_to_cpu(agf->agf_seqno);
+ __be32 *agfl_bno;
+ __be32 *blockp;
int error;
int logflags;
- xfs_mount_t *mp; /* mount structure */
- xfs_perag_t *pag; /* per allocation group data */
- __be32 *agfl_bno;
int startoff;
- agf = XFS_BUF_TO_AGF(agbp);
- mp = tp->t_mountp;
+ if (!agflbp) {
+ error = xfs_alloc_read_agfl(mp, tp, agno, &agflbp);
+ if (error)
+ return error;
+ }
- if (!agflbp && (error = xfs_alloc_read_agfl(mp, tp,
- be32_to_cpu(agf->agf_seqno), &agflbp)))
- return error;
- be32_add_cpu(&agf->agf_fllast, 1);
- if (be32_to_cpu(agf->agf_fllast) == xfs_agfl_size(mp))
- agf->agf_fllast = 0;
+ logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
- pag = xfs_perag_get(mp, be32_to_cpu(agf->agf_seqno));
- be32_add_cpu(&agf->agf_flcount, 1);
- xfs_trans_agflist_delta(tp, 1);
+ pag = xfs_perag_get(mp, agno);
pag->pagf_flcount++;
- pag->pagf_fllast = be32_to_cpu(agf->agf_fllast);
+ ASSERT(pag->pagf_flcount <= xfs_agfl_size(mp));
- logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
+ if (++pag->pagf_fllast == xfs_agfl_size(mp))
+ pag->pagf_fllast = 0;
+ xfs_trans_agflist_delta(tp, 1);
if (btreeblk) {
- be32_add_cpu(&agf->agf_btreeblks, -1);
pag->pagf_btreeblks--;
+ agf->agf_btreeblks = cpu_to_be32(pag->pagf_btreeblks);
logflags |= XFS_AGF_BTREEBLKS;
}
- xfs_perag_put(pag);
- xfs_alloc_log_agf(tp, agbp, logflags);
+ agf->agf_fllast = cpu_to_be32(pag->pagf_fllast);
+ agf->agf_flcount = cpu_to_be32(pag->pagf_flcount);
- ASSERT(be32_to_cpu(agf->agf_flcount) <= xfs_agfl_size(mp));
agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp);
- blockp = &agfl_bno[be32_to_cpu(agf->agf_fllast)];
+ blockp = &agfl_bno[pag->pagf_fllast];
*blockp = cpu_to_be32(bno);
startoff = (char *)blockp - (char *)agflbp->b_addr;
@@ -2400,6 +2394,7 @@ xfs_alloc_put_freelist(
xfs_trans_buf_set_type(tp, agflbp, XFS_BLFT_AGFL_BUF);
xfs_trans_log_buf(tp, agflbp, startoff,
startoff + sizeof(xfs_agblock_t) - 1);
+ xfs_perag_put(pag);
return 0;
}
@@ -2612,18 +2607,14 @@ xfs_agf_fixup_freelist_count(
pag->pag_agno);
if (pag->pagf_flcount) {
pag->pagf_flcount--;
- be32_add_cpu(&agf->agf_flcount, -1);
- be32_add_cpu(&agf->agf_fllast, -1);
pag->pagf_fllast--;
} else {
/* empty free list, move the both pointers back one */
ASSERT(pag->pagf_flfirst == pag->pagf_fllast);
- be32_add_cpu(&agf->agf_fllast, -1);
- be32_add_cpu(&agf->agf_flfirst, -1);
pag->pagf_flfirst--;
pag->pagf_fllast--;
}
- return;
+ goto out_update_agf;
}
/* if first is invalid, wrap it, reset count and return */
@@ -2633,10 +2624,8 @@ xfs_agf_fixup_freelist_count(
ASSERT(pag->pagf_flfirst != pag->pagf_fllast);
ASSERT(pag->pagf_flcount);
pag->pagf_flcount = pag->pagf_fllast + 1;
- agf->agf_flcount = cpu_to_be32(pag->pagf_flcount);
- agf->agf_flfirst = 0;
pag->pagf_flfirst = 0;
- return;
+ goto out_update_agf;
}
/*
@@ -2662,7 +2651,11 @@ xfs_agf_fixup_freelist_count(
xfs_notice(mp, "AGF %d: wrapped count fixup being performed",
pag->pag_agno);
pag->pagf_flcount--;
- be32_add_cpu(&agf->agf_flcount, -1);
+
+out_update_agf:
+ agf->agf_flfirst = cpu_to_be32(pag->pagf_flfirst);
+ agf->agf_fllast = cpu_to_be32(pag->pagf_fllast);
+ agf->agf_flcount = cpu_to_be32(pag->pagf_flcount);
}
/*