提交 55a7bc5a 编写于 作者: C Christoph Hellwig 提交者: Alex Elder

xfs: do not discard alloc btree blocks

Blocks for the allocation btree are allocated from and released to
the AGFL, and thus frequently reused.  Even worse we do not have an
easy way to avoid using an AGFL block when it is discarded due to
the simple FILO list of free blocks, and thus can frequently stall
on blocks that are currently undergoing a discard.

Add a flag to the busy extent tracking structure to skip the discard
for allocation btree blocks.  In normal operation these blocks are
reused frequently enough that there is no need to discard them
anyway, but if they spill over to the allocation btree as part of a
balance we "leak" blocks that we would otherwise discard.  We could
fix this by adding another flag and keeping these block in the
rbtree even after they aren't busy any more so that we could discard
them when they migrate out of the AGFL.  Given that this would cause
significant overhead I don't think it's worthwile for now.
Signed-off-by: NChristoph Hellwig <hch@lst.de>
Signed-off-by: NAlex Elder <aelder@sgi.com>
上级 e84661aa
...@@ -189,6 +189,7 @@ struct xfs_busy_extent { ...@@ -189,6 +189,7 @@ struct xfs_busy_extent {
xfs_extlen_t length; xfs_extlen_t length;
unsigned int flags; unsigned int flags;
#define XFS_ALLOC_BUSY_DISCARDED 0x01 /* undergoing a discard op. */ #define XFS_ALLOC_BUSY_DISCARDED 0x01 /* undergoing a discard op. */
#define XFS_ALLOC_BUSY_SKIP_DISCARD 0x02 /* do not discard */
}; };
/* /*
......
...@@ -2469,7 +2469,7 @@ xfs_free_extent( ...@@ -2469,7 +2469,7 @@ xfs_free_extent(
error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0);
if (!error) if (!error)
xfs_alloc_busy_insert(tp, args.agno, args.agbno, len); xfs_alloc_busy_insert(tp, args.agno, args.agbno, len, 0);
error0: error0:
xfs_perag_put(args.pag); xfs_perag_put(args.pag);
return error; return error;
...@@ -2480,7 +2480,8 @@ xfs_alloc_busy_insert( ...@@ -2480,7 +2480,8 @@ xfs_alloc_busy_insert(
struct xfs_trans *tp, struct xfs_trans *tp,
xfs_agnumber_t agno, xfs_agnumber_t agno,
xfs_agblock_t bno, xfs_agblock_t bno,
xfs_extlen_t len) xfs_extlen_t len,
unsigned int flags)
{ {
struct xfs_busy_extent *new; struct xfs_busy_extent *new;
struct xfs_busy_extent *busyp; struct xfs_busy_extent *busyp;
...@@ -2504,6 +2505,7 @@ xfs_alloc_busy_insert( ...@@ -2504,6 +2505,7 @@ xfs_alloc_busy_insert(
new->bno = bno; new->bno = bno;
new->length = len; new->length = len;
INIT_LIST_HEAD(&new->list); INIT_LIST_HEAD(&new->list);
new->flags = flags;
/* trace before insert to be able to see failed inserts */ /* trace before insert to be able to see failed inserts */
trace_xfs_alloc_busy(tp->t_mountp, agno, bno, len); trace_xfs_alloc_busy(tp->t_mountp, agno, bno, len);
...@@ -3018,7 +3020,8 @@ xfs_alloc_busy_clear( ...@@ -3018,7 +3020,8 @@ xfs_alloc_busy_clear(
agno = busyp->agno; agno = busyp->agno;
} }
if (do_discard && busyp->length) if (do_discard && busyp->length &&
!(busyp->flags & XFS_ALLOC_BUSY_SKIP_DISCARD))
busyp->flags = XFS_ALLOC_BUSY_DISCARDED; busyp->flags = XFS_ALLOC_BUSY_DISCARDED;
else else
xfs_alloc_busy_clear_one(mp, pag, busyp); xfs_alloc_busy_clear_one(mp, pag, busyp);
......
...@@ -137,7 +137,7 @@ xfs_alloc_longest_free_extent(struct xfs_mount *mp, ...@@ -137,7 +137,7 @@ xfs_alloc_longest_free_extent(struct xfs_mount *mp,
#ifdef __KERNEL__ #ifdef __KERNEL__
void void
xfs_alloc_busy_insert(struct xfs_trans *tp, xfs_agnumber_t agno, xfs_alloc_busy_insert(struct xfs_trans *tp, xfs_agnumber_t agno,
xfs_agblock_t bno, xfs_extlen_t len); xfs_agblock_t bno, xfs_extlen_t len, unsigned int flags);
void void
xfs_alloc_busy_clear(struct xfs_mount *mp, struct list_head *list, xfs_alloc_busy_clear(struct xfs_mount *mp, struct list_head *list,
......
...@@ -120,7 +120,8 @@ xfs_allocbt_free_block( ...@@ -120,7 +120,8 @@ xfs_allocbt_free_block(
if (error) if (error)
return error; return error;
xfs_alloc_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1); xfs_alloc_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1,
XFS_ALLOC_BUSY_SKIP_DISCARD);
xfs_trans_agbtree_delta(cur->bc_tp, -1); xfs_trans_agbtree_delta(cur->bc_tp, -1);
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册