aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-02-22 17:41:25 -0500
committerDarrick J. Wong <darrick.wong@oracle.com>2018-02-22 17:41:25 -0500
commitb31c2bdcd83e3374fec5a8e27a2fb4d26e771c52 (patch)
treeff512e9c22ca3de3733bbe334bc580c1e96d6503
parent86516eff3b09a5fd17e81d50925bbccc6a36beed (diff)
xfs: reserve blocks for refcount / rmap log item recovery
During log recovery, the per-AG reservations aren't yet set up, so log recovery has to reserve enough blocks to handle all possible btree splits. Reported-by: Dave Chinner <david@fromorbit.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com>
-rw-r--r--fs/xfs/xfs_refcount_item.c9
-rw-r--r--fs/xfs/xfs_rmap_item.c4
2 files changed, 9 insertions, 4 deletions
diff --git a/fs/xfs/xfs_refcount_item.c b/fs/xfs/xfs_refcount_item.c
index 3a55d6fc271b..7a39f40645f7 100644
--- a/fs/xfs/xfs_refcount_item.c
+++ b/fs/xfs/xfs_refcount_item.c
@@ -23,6 +23,7 @@
23#include "xfs_log_format.h" 23#include "xfs_log_format.h"
24#include "xfs_trans_resv.h" 24#include "xfs_trans_resv.h"
25#include "xfs_bit.h" 25#include "xfs_bit.h"
26#include "xfs_shared.h"
26#include "xfs_mount.h" 27#include "xfs_mount.h"
27#include "xfs_defer.h" 28#include "xfs_defer.h"
28#include "xfs_trans.h" 29#include "xfs_trans.h"
@@ -456,10 +457,12 @@ xfs_cui_recover(
456 * transaction. Normally, any work that needs to be deferred 457 * transaction. Normally, any work that needs to be deferred
457 * gets attached to the same defer_ops that scheduled the 458 * gets attached to the same defer_ops that scheduled the
458 * refcount update. However, we're in log recovery here, so we 459 * refcount update. However, we're in log recovery here, so we
459 * we create our own defer_ops and use that to finish up any 460 * we use the passed in defer_ops and to finish up any work that
460 * work that doesn't fit. 461 * doesn't fit. We need to reserve enough blocks to handle a
462 * full btree split on either end of the refcount range.
461 */ 463 */
462 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); 464 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
465 mp->m_refc_maxlevels * 2, 0, XFS_TRANS_RESERVE, &tp);
463 if (error) 466 if (error)
464 return error; 467 return error;
465 cudp = xfs_trans_get_cud(tp, cuip); 468 cudp = xfs_trans_get_cud(tp, cuip);
diff --git a/fs/xfs/xfs_rmap_item.c b/fs/xfs/xfs_rmap_item.c
index f3b139c9aa16..49d3124863a8 100644
--- a/fs/xfs/xfs_rmap_item.c
+++ b/fs/xfs/xfs_rmap_item.c
@@ -23,6 +23,7 @@
23#include "xfs_log_format.h" 23#include "xfs_log_format.h"
24#include "xfs_trans_resv.h" 24#include "xfs_trans_resv.h"
25#include "xfs_bit.h" 25#include "xfs_bit.h"
26#include "xfs_shared.h"
26#include "xfs_mount.h" 27#include "xfs_mount.h"
27#include "xfs_defer.h" 28#include "xfs_defer.h"
28#include "xfs_trans.h" 29#include "xfs_trans.h"
@@ -470,7 +471,8 @@ xfs_rui_recover(
470 } 471 }
471 } 472 }
472 473
473 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); 474 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate,
475 mp->m_rmap_maxlevels, 0, XFS_TRANS_RESERVE, &tp);
474 if (error) 476 if (error)
475 return error; 477 return error;
476 rudp = xfs_trans_get_rud(tp, ruip); 478 rudp = xfs_trans_get_rud(tp, ruip);