aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2016-08-02 21:37:10 -0400
committerDave Chinner <david@fromorbit.com>2016-08-02 21:37:10 -0400
commitfa30f03cda26783b1294af6e7da9f1142da0f52e (patch)
tree4585fb561e4c40306bea25fbc41121649641b8c8
parente70d829f8d288cd062d265085420f001828b0683 (diff)
xfs: rmap btree transaction reservations
The rmap btrees will use the AGFL as the block allocation source, so we need to ensure that the transaction reservations reflect the fact this tree is modified by allocation and freeing. Hence we need to extend all the extent allocation/free reservations used in transactions to handle this. Note that this also gets rid of the unused XFS_ALLOCFREE_LOG_RES macro, as we now do buffer reservations based on the number of buffers logged via xfs_calc_buf_res(). Hence we only need the buffer count calculation now. [darrick: use rmap_maxlevels when calculating log block resv] Signed-off-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r--fs/xfs/libxfs/xfs_trans_resv.c58
-rw-r--r--fs/xfs/libxfs/xfs_trans_resv.h10
2 files changed, 41 insertions, 27 deletions
diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
index 4c7eb9d7c0c7..301ef2f4dbd6 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.c
+++ b/fs/xfs/libxfs/xfs_trans_resv.c
@@ -64,6 +64,30 @@ xfs_calc_buf_res(
64} 64}
65 65
66/* 66/*
67 * Per-extent log reservation for the btree changes involved in freeing or
68 * allocating an extent. In classic XFS there were two trees that will be
69 * modified (bnobt + cntbt). With rmap enabled, there are three trees
70 * (rmapbt). The number of blocks reserved is based on the formula:
71 *
72 * num trees * ((2 blocks/level * max depth) - 1)
73 *
74 * Keep in mind that max depth is calculated separately for each type of tree.
75 */
76static uint
77xfs_allocfree_log_count(
78 struct xfs_mount *mp,
79 uint num_ops)
80{
81 uint blocks;
82
83 blocks = num_ops * 2 * (2 * mp->m_ag_maxlevels - 1);
84 if (xfs_sb_version_hasrmapbt(&mp->m_sb))
85 blocks += num_ops * (2 * mp->m_rmap_maxlevels - 1);
86
87 return blocks;
88}
89
90/*
67 * Logging inodes is really tricksy. They are logged in memory format, 91 * Logging inodes is really tricksy. They are logged in memory format,
68 * which means that what we write into the log doesn't directly translate into 92 * which means that what we write into the log doesn't directly translate into
69 * the amount of space they use on disk. 93 * the amount of space they use on disk.
@@ -126,7 +150,7 @@ xfs_calc_inode_res(
126 */ 150 */
127STATIC uint 151STATIC uint
128xfs_calc_finobt_res( 152xfs_calc_finobt_res(
129 struct xfs_mount *mp, 153 struct xfs_mount *mp,
130 int alloc, 154 int alloc,
131 int modify) 155 int modify)
132{ 156{
@@ -137,7 +161,7 @@ xfs_calc_finobt_res(
137 161
138 res = xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)); 162 res = xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1));
139 if (alloc) 163 if (alloc)
140 res += xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 164 res += xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
141 XFS_FSB_TO_B(mp, 1)); 165 XFS_FSB_TO_B(mp, 1));
142 if (modify) 166 if (modify)
143 res += (uint)XFS_FSB_TO_B(mp, 1); 167 res += (uint)XFS_FSB_TO_B(mp, 1);
@@ -188,10 +212,10 @@ xfs_calc_write_reservation(
188 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 212 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK),
189 XFS_FSB_TO_B(mp, 1)) + 213 XFS_FSB_TO_B(mp, 1)) +
190 xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 214 xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
191 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), 215 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2),
192 XFS_FSB_TO_B(mp, 1))), 216 XFS_FSB_TO_B(mp, 1))),
193 (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + 217 (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
194 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), 218 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2),
195 XFS_FSB_TO_B(mp, 1)))); 219 XFS_FSB_TO_B(mp, 1))));
196} 220}
197 221
@@ -217,10 +241,10 @@ xfs_calc_itruncate_reservation(
217 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1, 241 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1,
218 XFS_FSB_TO_B(mp, 1))), 242 XFS_FSB_TO_B(mp, 1))),
219 (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + 243 (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
220 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4), 244 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4),
221 XFS_FSB_TO_B(mp, 1)) + 245 XFS_FSB_TO_B(mp, 1)) +
222 xfs_calc_buf_res(5, 0) + 246 xfs_calc_buf_res(5, 0) +
223 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 247 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
224 XFS_FSB_TO_B(mp, 1)) + 248 XFS_FSB_TO_B(mp, 1)) +
225 xfs_calc_buf_res(2 + mp->m_ialloc_blks + 249 xfs_calc_buf_res(2 + mp->m_ialloc_blks +
226 mp->m_in_maxlevels, 0))); 250 mp->m_in_maxlevels, 0)));
@@ -247,7 +271,7 @@ xfs_calc_rename_reservation(
247 xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp), 271 xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp),
248 XFS_FSB_TO_B(mp, 1))), 272 XFS_FSB_TO_B(mp, 1))),
249 (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) + 273 (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) +
250 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 3), 274 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 3),
251 XFS_FSB_TO_B(mp, 1)))); 275 XFS_FSB_TO_B(mp, 1))));
252} 276}
253 277
@@ -286,7 +310,7 @@ xfs_calc_link_reservation(
286 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), 310 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
287 XFS_FSB_TO_B(mp, 1))), 311 XFS_FSB_TO_B(mp, 1))),
288 (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 312 (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
289 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 313 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
290 XFS_FSB_TO_B(mp, 1)))); 314 XFS_FSB_TO_B(mp, 1))));
291} 315}
292 316
@@ -324,7 +348,7 @@ xfs_calc_remove_reservation(
324 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), 348 xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
325 XFS_FSB_TO_B(mp, 1))), 349 XFS_FSB_TO_B(mp, 1))),
326 (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) + 350 (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) +
327 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), 351 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2),
328 XFS_FSB_TO_B(mp, 1)))); 352 XFS_FSB_TO_B(mp, 1))));
329} 353}
330 354
@@ -371,7 +395,7 @@ xfs_calc_create_resv_alloc(
371 mp->m_sb.sb_sectsize + 395 mp->m_sb.sb_sectsize +
372 xfs_calc_buf_res(mp->m_ialloc_blks, XFS_FSB_TO_B(mp, 1)) + 396 xfs_calc_buf_res(mp->m_ialloc_blks, XFS_FSB_TO_B(mp, 1)) +
373 xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) + 397 xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
374 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 398 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
375 XFS_FSB_TO_B(mp, 1)); 399 XFS_FSB_TO_B(mp, 1));
376} 400}
377 401
@@ -399,7 +423,7 @@ xfs_calc_icreate_resv_alloc(
399 return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + 423 return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
400 mp->m_sb.sb_sectsize + 424 mp->m_sb.sb_sectsize +
401 xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) + 425 xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
402 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 426 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
403 XFS_FSB_TO_B(mp, 1)) + 427 XFS_FSB_TO_B(mp, 1)) +
404 xfs_calc_finobt_res(mp, 0, 0); 428 xfs_calc_finobt_res(mp, 0, 0);
405} 429}
@@ -483,7 +507,7 @@ xfs_calc_ifree_reservation(
483 xfs_calc_buf_res(1, 0) + 507 xfs_calc_buf_res(1, 0) +
484 xfs_calc_buf_res(2 + mp->m_ialloc_blks + 508 xfs_calc_buf_res(2 + mp->m_ialloc_blks +
485 mp->m_in_maxlevels, 0) + 509 mp->m_in_maxlevels, 0) +
486 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 510 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
487 XFS_FSB_TO_B(mp, 1)) + 511 XFS_FSB_TO_B(mp, 1)) +
488 xfs_calc_finobt_res(mp, 0, 1); 512 xfs_calc_finobt_res(mp, 0, 1);
489} 513}
@@ -513,7 +537,7 @@ xfs_calc_growdata_reservation(
513 struct xfs_mount *mp) 537 struct xfs_mount *mp)
514{ 538{
515 return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + 539 return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
516 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 540 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
517 XFS_FSB_TO_B(mp, 1)); 541 XFS_FSB_TO_B(mp, 1));
518} 542}
519 543
@@ -535,7 +559,7 @@ xfs_calc_growrtalloc_reservation(
535 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 559 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK),
536 XFS_FSB_TO_B(mp, 1)) + 560 XFS_FSB_TO_B(mp, 1)) +
537 xfs_calc_inode_res(mp, 1) + 561 xfs_calc_inode_res(mp, 1) +
538 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 562 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
539 XFS_FSB_TO_B(mp, 1)); 563 XFS_FSB_TO_B(mp, 1));
540} 564}
541 565
@@ -611,7 +635,7 @@ xfs_calc_addafork_reservation(
611 xfs_calc_buf_res(1, mp->m_dir_geo->blksize) + 635 xfs_calc_buf_res(1, mp->m_dir_geo->blksize) +
612 xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1, 636 xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1,
613 XFS_FSB_TO_B(mp, 1)) + 637 XFS_FSB_TO_B(mp, 1)) +
614 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), 638 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
615 XFS_FSB_TO_B(mp, 1)); 639 XFS_FSB_TO_B(mp, 1));
616} 640}
617 641
@@ -634,7 +658,7 @@ xfs_calc_attrinval_reservation(
634 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK), 658 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK),
635 XFS_FSB_TO_B(mp, 1))), 659 XFS_FSB_TO_B(mp, 1))),
636 (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + 660 (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
637 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4), 661 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4),
638 XFS_FSB_TO_B(mp, 1)))); 662 XFS_FSB_TO_B(mp, 1))));
639} 663}
640 664
@@ -701,7 +725,7 @@ xfs_calc_attrrm_reservation(
701 XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + 725 XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +
702 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)), 726 xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)),
703 (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + 727 (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
704 xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), 728 xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2),
705 XFS_FSB_TO_B(mp, 1)))); 729 XFS_FSB_TO_B(mp, 1))));
706} 730}
707 731
diff --git a/fs/xfs/libxfs/xfs_trans_resv.h b/fs/xfs/libxfs/xfs_trans_resv.h
index 797815012c0e..0eb46ed6d404 100644
--- a/fs/xfs/libxfs/xfs_trans_resv.h
+++ b/fs/xfs/libxfs/xfs_trans_resv.h
@@ -68,16 +68,6 @@ struct xfs_trans_resv {
68#define M_RES(mp) (&(mp)->m_resv) 68#define M_RES(mp) (&(mp)->m_resv)
69 69
70/* 70/*
71 * Per-extent log reservation for the allocation btree changes
72 * involved in freeing or allocating an extent.
73 * 2 trees * (2 blocks/level * max depth - 1) * block size
74 */
75#define XFS_ALLOCFREE_LOG_RES(mp,nx) \
76 ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * (mp)->m_ag_maxlevels - 1)))
77#define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \
78 ((nx) * (2 * (2 * (mp)->m_ag_maxlevels - 1)))
79
80/*
81 * Per-directory log reservation for any directory change. 71 * Per-directory log reservation for any directory change.
82 * dir blocks: (1 btree block per level + data block + free block) * dblock size 72 * dir blocks: (1 btree block per level + data block + free block) * dblock size
83 * bmap btree: (levels + 2) * max depth * block size 73 * bmap btree: (levels + 2) * max depth * block size