@@ -65,6 +65,7 @@ void xfs_log_get_max_trans_res(struct xfs_mount *mp,
#define XFS_TRANS_DQ_DIRTY 0x10 /* at least one dquot in trx dirty */
#define XFS_TRANS_RESERVE 0x20 /* OK to use reserved data blocks */
#define XFS_TRANS_NO_WRITECOUNT 0x40 /* do not elevate SB writecount */
+#define XFS_TRANS_RELOG 0x80 /* requires extra relog overhead */
/*
* LOWMODE is used by the allocator to activate the lowspace algorithm - when
* free space is running low the extent allocator may choose to allocate an
@@ -418,7 +418,8 @@ xfs_log_reserve(
int cnt,
struct xlog_ticket **ticp,
uint8_t client,
- bool permanent)
+ bool permanent,
+ bool relog)
{
struct xlog *log = mp->m_log;
struct xlog_ticket *tic;
@@ -433,7 +434,8 @@ xfs_log_reserve(
XFS_STATS_INC(mp, xs_try_logspace);
ASSERT(*ticp == NULL);
- tic = xlog_ticket_alloc(log, unit_bytes, cnt, client, permanent, 0);
+ tic = xlog_ticket_alloc(log, unit_bytes, cnt, client, permanent, relog,
+ 0);
*ticp = tic;
xlog_grant_push_ail(log, tic->t_cnt ? tic->t_unit_res * tic->t_cnt
@@ -831,7 +833,7 @@ xlog_unmount_write(
uint flags = XLOG_UNMOUNT_TRANS;
int error;
- error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0);
+ error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, false, false);
if (error)
goto out_err;
@@ -3421,6 +3423,7 @@ xlog_ticket_alloc(
int cnt,
char client,
bool permanent,
+ bool relog,
xfs_km_flags_t alloc_flags)
{
struct xlog_ticket *tic;
@@ -3431,6 +3434,9 @@ xlog_ticket_alloc(
return NULL;
unit_res = xfs_log_calc_unit_res(log->l_mp, unit_bytes);
+ /* double the overhead for the relog transaction */
+ if (relog)
+ unit_res += (unit_res - unit_bytes);
atomic_set(&tic->t_ref, 1);
tic->t_task = current;
@@ -123,7 +123,8 @@ int xfs_log_reserve(struct xfs_mount *mp,
int count,
struct xlog_ticket **ticket,
uint8_t clientid,
- bool permanent);
+ bool permanent,
+ bool relog);
int xfs_log_regrant(struct xfs_mount *mp, struct xlog_ticket *tic);
void xfs_log_ungrant_bytes(struct xfs_mount *mp, int bytes);
void xfs_log_unmount(struct xfs_mount *mp);
@@ -37,7 +37,7 @@ xlog_cil_ticket_alloc(
{
struct xlog_ticket *tic;
- tic = xlog_ticket_alloc(log, 0, 1, XFS_TRANSACTION, 0,
+ tic = xlog_ticket_alloc(log, 0, 1, XFS_TRANSACTION, false, false,
KM_NOFS);
/*
@@ -465,6 +465,7 @@ xlog_ticket_alloc(
int count,
char client,
bool permanent,
+ bool relog,
xfs_km_flags_t alloc_flags);
@@ -174,6 +174,7 @@ xfs_trans_reserve(
*/
if (resp->tr_logres > 0) {
bool permanent = false;
+ bool relog = (tp->t_flags & XFS_TRANS_RELOG);
ASSERT(tp->t_log_res == 0 ||
tp->t_log_res == resp->tr_logres);
@@ -196,7 +197,7 @@ xfs_trans_reserve(
resp->tr_logres,
resp->tr_logcount,
&tp->t_ticket, XFS_TRANSACTION,
- permanent);
+ permanent, relog);
}
if (error)