|
@@ -1447,7 +1447,8 @@ xfs_alloc_ag_vextent_small(
|
|
else if (args->minlen == 1 && args->alignment == 1 && !args->isfl &&
|
|
else if (args->minlen == 1 && args->alignment == 1 && !args->isfl &&
|
|
(be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
|
|
(be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_flcount)
|
|
> args->minleft)) {
|
|
> args->minleft)) {
|
|
- if ((error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno)))
|
|
|
|
|
|
+ error = xfs_alloc_get_freelist(args->tp, args->agbp, &fbno, 0);
|
|
|
|
+ if (error)
|
|
goto error0;
|
|
goto error0;
|
|
if (fbno != NULLAGBLOCK) {
|
|
if (fbno != NULLAGBLOCK) {
|
|
if (args->userdata) {
|
|
if (args->userdata) {
|
|
@@ -1923,7 +1924,8 @@ xfs_alloc_fix_freelist(
|
|
while (be32_to_cpu(agf->agf_flcount) > need) {
|
|
while (be32_to_cpu(agf->agf_flcount) > need) {
|
|
xfs_buf_t *bp;
|
|
xfs_buf_t *bp;
|
|
|
|
|
|
- if ((error = xfs_alloc_get_freelist(tp, agbp, &bno)))
|
|
|
|
|
|
+ error = xfs_alloc_get_freelist(tp, agbp, &bno, 0);
|
|
|
|
+ if (error)
|
|
return error;
|
|
return error;
|
|
if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1)))
|
|
if ((error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1)))
|
|
return error;
|
|
return error;
|
|
@@ -1973,8 +1975,9 @@ xfs_alloc_fix_freelist(
|
|
* Put each allocated block on the list.
|
|
* Put each allocated block on the list.
|
|
*/
|
|
*/
|
|
for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) {
|
|
for (bno = targs.agbno; bno < targs.agbno + targs.len; bno++) {
|
|
- if ((error = xfs_alloc_put_freelist(tp, agbp, agflbp,
|
|
|
|
- bno)))
|
|
|
|
|
|
+ error = xfs_alloc_put_freelist(tp, agbp,
|
|
|
|
+ agflbp, bno, 0);
|
|
|
|
+ if (error)
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1991,13 +1994,15 @@ int /* error */
|
|
xfs_alloc_get_freelist(
|
|
xfs_alloc_get_freelist(
|
|
xfs_trans_t *tp, /* transaction pointer */
|
|
xfs_trans_t *tp, /* transaction pointer */
|
|
xfs_buf_t *agbp, /* buffer containing the agf structure */
|
|
xfs_buf_t *agbp, /* buffer containing the agf structure */
|
|
- xfs_agblock_t *bnop) /* block address retrieved from freelist */
|
|
|
|
|
|
+ xfs_agblock_t *bnop, /* block address retrieved from freelist */
|
|
|
|
+ int btreeblk) /* destination is a AGF btree */
|
|
{
|
|
{
|
|
xfs_agf_t *agf; /* a.g. freespace structure */
|
|
xfs_agf_t *agf; /* a.g. freespace structure */
|
|
xfs_agfl_t *agfl; /* a.g. freelist structure */
|
|
xfs_agfl_t *agfl; /* a.g. freelist structure */
|
|
xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */
|
|
xfs_buf_t *agflbp;/* buffer for a.g. freelist structure */
|
|
xfs_agblock_t bno; /* block number returned */
|
|
xfs_agblock_t bno; /* block number returned */
|
|
int error;
|
|
int error;
|
|
|
|
+ int logflags;
|
|
#ifdef XFS_ALLOC_TRACE
|
|
#ifdef XFS_ALLOC_TRACE
|
|
static char fname[] = "xfs_alloc_get_freelist";
|
|
static char fname[] = "xfs_alloc_get_freelist";
|
|
#endif
|
|
#endif
|
|
@@ -2032,8 +2037,16 @@ xfs_alloc_get_freelist(
|
|
be32_add(&agf->agf_flcount, -1);
|
|
be32_add(&agf->agf_flcount, -1);
|
|
xfs_trans_agflist_delta(tp, -1);
|
|
xfs_trans_agflist_delta(tp, -1);
|
|
pag->pagf_flcount--;
|
|
pag->pagf_flcount--;
|
|
- TRACE_MODAGF(NULL, agf, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT);
|
|
|
|
- xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT);
|
|
|
|
|
|
+
|
|
|
|
+ logflags = XFS_AGF_FLFIRST | XFS_AGF_FLCOUNT;
|
|
|
|
+ if (btreeblk) {
|
|
|
|
+ be32_add(&agf->agf_btreeblks, 1);
|
|
|
|
+ pag->pagf_btreeblks++;
|
|
|
|
+ logflags |= XFS_AGF_BTREEBLKS;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TRACE_MODAGF(NULL, agf, logflags);
|
|
|
|
+ xfs_alloc_log_agf(tp, agbp, logflags);
|
|
*bnop = bno;
|
|
*bnop = bno;
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -2071,6 +2084,7 @@ xfs_alloc_log_agf(
|
|
offsetof(xfs_agf_t, agf_flcount),
|
|
offsetof(xfs_agf_t, agf_flcount),
|
|
offsetof(xfs_agf_t, agf_freeblks),
|
|
offsetof(xfs_agf_t, agf_freeblks),
|
|
offsetof(xfs_agf_t, agf_longest),
|
|
offsetof(xfs_agf_t, agf_longest),
|
|
|
|
+ offsetof(xfs_agf_t, agf_btreeblks),
|
|
sizeof(xfs_agf_t)
|
|
sizeof(xfs_agf_t)
|
|
};
|
|
};
|
|
|
|
|
|
@@ -2106,12 +2120,14 @@ xfs_alloc_put_freelist(
|
|
xfs_trans_t *tp, /* transaction pointer */
|
|
xfs_trans_t *tp, /* transaction pointer */
|
|
xfs_buf_t *agbp, /* buffer for a.g. freelist header */
|
|
xfs_buf_t *agbp, /* buffer for a.g. freelist header */
|
|
xfs_buf_t *agflbp,/* buffer for a.g. free block array */
|
|
xfs_buf_t *agflbp,/* buffer for a.g. free block array */
|
|
- xfs_agblock_t bno) /* block being freed */
|
|
|
|
|
|
+ xfs_agblock_t bno, /* block being freed */
|
|
|
|
+ int btreeblk) /* block came from a AGF btree */
|
|
{
|
|
{
|
|
xfs_agf_t *agf; /* a.g. freespace structure */
|
|
xfs_agf_t *agf; /* a.g. freespace structure */
|
|
xfs_agfl_t *agfl; /* a.g. free block array */
|
|
xfs_agfl_t *agfl; /* a.g. free block array */
|
|
__be32 *blockp;/* pointer to array entry */
|
|
__be32 *blockp;/* pointer to array entry */
|
|
int error;
|
|
int error;
|
|
|
|
+ int logflags;
|
|
#ifdef XFS_ALLOC_TRACE
|
|
#ifdef XFS_ALLOC_TRACE
|
|
static char fname[] = "xfs_alloc_put_freelist";
|
|
static char fname[] = "xfs_alloc_put_freelist";
|
|
#endif
|
|
#endif
|
|
@@ -2132,11 +2148,22 @@ xfs_alloc_put_freelist(
|
|
be32_add(&agf->agf_flcount, 1);
|
|
be32_add(&agf->agf_flcount, 1);
|
|
xfs_trans_agflist_delta(tp, 1);
|
|
xfs_trans_agflist_delta(tp, 1);
|
|
pag->pagf_flcount++;
|
|
pag->pagf_flcount++;
|
|
|
|
+
|
|
|
|
+ logflags = XFS_AGF_FLLAST | XFS_AGF_FLCOUNT;
|
|
|
|
+ if (btreeblk) {
|
|
|
|
+ be32_add(&agf->agf_btreeblks, -1);
|
|
|
|
+ pag->pagf_btreeblks--;
|
|
|
|
+ logflags |= XFS_AGF_BTREEBLKS;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ TRACE_MODAGF(NULL, agf, logflags);
|
|
|
|
+ xfs_alloc_log_agf(tp, agbp, logflags);
|
|
|
|
+
|
|
ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
|
|
ASSERT(be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp));
|
|
blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)];
|
|
blockp = &agfl->agfl_bno[be32_to_cpu(agf->agf_fllast)];
|
|
*blockp = cpu_to_be32(bno);
|
|
*blockp = cpu_to_be32(bno);
|
|
- TRACE_MODAGF(NULL, agf, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
|
|
|
|
- xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
|
|
|
|
|
|
+ TRACE_MODAGF(NULL, agf, logflags);
|
|
|
|
+ xfs_alloc_log_agf(tp, agbp, logflags);
|
|
xfs_trans_log_buf(tp, agflbp,
|
|
xfs_trans_log_buf(tp, agflbp,
|
|
(int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl),
|
|
(int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl),
|
|
(int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl +
|
|
(int)((xfs_caddr_t)blockp - (xfs_caddr_t)agfl +
|
|
@@ -2196,6 +2223,7 @@ xfs_alloc_read_agf(
|
|
pag = &mp->m_perag[agno];
|
|
pag = &mp->m_perag[agno];
|
|
if (!pag->pagf_init) {
|
|
if (!pag->pagf_init) {
|
|
pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
|
|
pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
|
|
|
|
+ pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
|
|
pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
|
|
pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
|
|
pag->pagf_longest = be32_to_cpu(agf->agf_longest);
|
|
pag->pagf_longest = be32_to_cpu(agf->agf_longest);
|
|
pag->pagf_levels[XFS_BTNUM_BNOi] =
|
|
pag->pagf_levels[XFS_BTNUM_BNOi] =
|