mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
xfs: account for the refcount btree in the alloc/free log reservation
Every time we allocate or free a data extent, we might need to split the refcount btree. Reserve some blocks in the transaction to handle this possibility. Even though the deferred refcount code can roll a transaction to avoid overloading the transaction, we can still exceed the reservation. Certain pathological workloads (1k blocks, no cowextsize hint, random directio writes), cause a perfect storm wherein a refcount adjustment of a large range of blocks causes full tree splits in two separate extents in two separate refcount tree blocks; allocating new refcount tree blocks causes rmap btree splits; and all the allocation activity causes the freespace btrees to split, blowing the reservation. (Reproduced by generic/167 over NFS atop XFS) Signed-off-by: Christoph Hellwig <hch@lst.de> [darrick.wong@oracle.com: add commit message] Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
parent
ac4fef6938
commit
f310bd2ecd
1 changed files with 4 additions and 1 deletions
|
@ -67,7 +67,8 @@ xfs_calc_buf_res(
|
|||
* Per-extent log reservation for the btree changes involved in freeing or
|
||||
* allocating an extent. In classic XFS there were two trees that will be
|
||||
* modified (bnobt + cntbt). With rmap enabled, there are three trees
|
||||
* (rmapbt). The number of blocks reserved is based on the formula:
|
||||
* (rmapbt). With reflink, there are four trees (refcountbt). The number of
|
||||
* blocks reserved is based on the formula:
|
||||
*
|
||||
* num trees * ((2 blocks/level * max depth) - 1)
|
||||
*
|
||||
|
@ -83,6 +84,8 @@ xfs_allocfree_log_count(
|
|||
blocks = num_ops * 2 * (2 * mp->m_ag_maxlevels - 1);
|
||||
if (xfs_sb_version_hasrmapbt(&mp->m_sb))
|
||||
blocks += num_ops * (2 * mp->m_rmap_maxlevels - 1);
|
||||
if (xfs_sb_version_hasreflink(&mp->m_sb))
|
||||
blocks += num_ops * (2 * mp->m_refc_maxlevels - 1);
|
||||
|
||||
return blocks;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue