diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-01-05 17:45:54 -0800 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-03-25 17:08:43 -0700 |
commit | 11881b3f390e13c0e929eadb9fe6be8c4192861d (patch) | |
tree | 95ae0d64b484043b8601561e45eb3aa9f52c3c3c /fs | |
parent | 5acbb872f7d828f132ea24de00b0cb96a707f2ee (diff) |
xfs: realtime rmap btree transaction reservations
Make sure that there's enough log reservation to handle mapping
and unmapping realtime extents. We have to reserve enough space
to handle a split in the rtrmapbt to add the record and a second
split in the regular rmapbt to record the rtrmapbt split.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/libxfs/xfs_trans_resv.c | 17 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_trans_space.h | 13 |
2 files changed, 26 insertions, 4 deletions
diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index 6cc901684ea6..142f718945ec 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -210,7 +210,9 @@ xfs_calc_inode_chunk_res( * Per-extent log reservation for the btree changes involved in freeing or * allocating a realtime extent. We have to be able to log as many rtbitmap * blocks as needed to mark inuse MAXEXTLEN blocks' worth of realtime extents, - * as well as the realtime summary block. + * as well as the realtime summary block (t1). Realtime rmap btree operations + * happen in a second transaction, so factor in a couple of rtrmapbt splits + * (t2). */ static unsigned int xfs_rtalloc_log_count( @@ -219,9 +221,15 @@ xfs_rtalloc_log_count( { unsigned int blksz = XFS_FSB_TO_B(mp, 1); unsigned int rtbmp_bytes; + unsigned int t1, t2 = 0; rtbmp_bytes = (MAXEXTLEN / mp->m_sb.sb_rextsize) / NBBY; - return (howmany(rtbmp_bytes, blksz) + 1) * num_ops; + t1 = (howmany(rtbmp_bytes, blksz) + 1) * num_ops; + + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + t2 = num_ops * (2 * mp->m_rtrmap_maxlevels - 1); + + return max(t1, t2); } /* @@ -1119,8 +1127,9 @@ xfs_trans_resv_calc_logsize( ASSERT(resp != M_RES(mp)); /* - * The metadata directory tree feature drops the oversized log - * reservations introduced by reflink and rmap. + * The metadata directory tree feature (as well as realtime reflink and + * or rmap) drop the oversized log reservations introduced by reflink + * and rmap. */ if (xfs_sb_version_hasmetadir(&mp->m_sb)) { xfs_trans_resv_calc(mp, resp); diff --git a/fs/xfs/libxfs/xfs_trans_space.h b/fs/xfs/libxfs/xfs_trans_space.h index 406ad6ab0467..9234a0138cd6 100644 --- a/fs/xfs/libxfs/xfs_trans_space.h +++ b/fs/xfs/libxfs/xfs_trans_space.h @@ -10,6 +10,19 @@ * Components of space reservations. */ +/* Worst case number of realtime rmaps that can be held in a block. */ +#define XFS_MAX_CONTIG_RTRMAPS_PER_BLOCK(mp) \ + (((mp)->m_rtrmap_mxr[0]) - ((mp)->m_rtrmap_mnr[0])) + +/* Adding one realtime rmap could split every level to the top of the tree. */ +#define XFS_RTRMAPADD_SPACE_RES(mp) ((mp)->m_rtrmap_maxlevels) + +/* Blocks we might need to add "b" realtime rmaps to a tree. */ +#define XFS_NRTRMAPADD_SPACE_RES(mp, b) \ + ((((b) + XFS_MAX_CONTIG_RTRMAPS_PER_BLOCK(mp) - 1) / \ + XFS_MAX_CONTIG_RTRMAPS_PER_BLOCK(mp)) * \ + XFS_RTRMAPADD_SPACE_RES(mp)) + /* Worst case number of rmaps that can be held in a block. */ #define XFS_MAX_CONTIG_RMAPS_PER_BLOCK(mp) \ (((mp)->m_rmap_mxr[0]) - ((mp)->m_rmap_mnr[0])) |