Re: block allocations for the refcount btree

Darrick J. Wong
2016-03-02T21:21:36Z

On Wed, Mar 02, 2016 at 08:57:04AM -0800, Christoph Hellwig wrote:
> On Wed, Mar 02, 2016 at 08:41:02AM -0800, Darrick J. Wong wrote:
> > Hmm, I'll give it a spin when I get in later. Can you send me xfs_info
> > output so I can try to construct an equivalent reproducer setup?
>
> root@vm:~/xfstests# xfs_info /mnt/scratch/
> meta-data=/dev/vdc isize=512 agcount=320, agsize=8192 blks
> = sectsz=512 attr=2, projid32bit=1
> = crc=1 finobt=1 spinodes=0 rmapbt=0
> = reflink=1
> data = bsize=4096 blocks=2621440, imaxpct=25
> = sunit=0 swidth=0 blks
> naming =version 2 bsize=4096 ascii-ci=0 ftype=1
> log =internal bsize=4096 blocks=2560, version=2
> = sectsz=512 sunit=0 blks, lazy-count=1
> realtime =none extsz=4096 blocks=0, rtextents=0

Ok. I think the problem is that making changes to the refcount btree eats
up our entire reservation in certain cases. Can you try the following bandaid?
This should give us enough room to handle splitting the btree at both ends
of a range that we're refcount-changing.

Come to think of it, this might not be enough -- if we want to change the
refcount of an n-block extent, can we end up changing n/i_refc_mnr[0] blocks?
I suspect yes, but I'll think about that some more.

diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
index cfd8a3c..54c5c22 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.c
+++ b/fs/xfs/libxfs/xfs_trans_resv.c
@@ -86,7 +86,7 @@ xfs_allocfree_log_count(
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);
+ blocks += 2 * num_ops * (2 * mp->m_refc_maxlevels - 1);
return blocks;
}