xfs: factor and move some code in xfs_log_cil.c
In preparation for adding support for intent item whiteouts. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Allison Henderson <allison.henderson@oracle.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
bb7b1c9c5d
commit
22b1afc57e
|
@ -47,6 +47,38 @@ xlog_cil_ticket_alloc(
|
||||||
return tic;
|
return tic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the current log item was first committed in this sequence.
|
||||||
|
* We can't rely on just the log item being in the CIL, we have to check
|
||||||
|
* the recorded commit sequence number.
|
||||||
|
*
|
||||||
|
* Note: for this to be used in a non-racy manner, it has to be called with
|
||||||
|
* CIL flushing locked out. As a result, it should only be used during the
|
||||||
|
* transaction commit process when deciding what to format into the item.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
xlog_item_in_current_chkpt(
|
||||||
|
struct xfs_cil *cil,
|
||||||
|
struct xfs_log_item *lip)
|
||||||
|
{
|
||||||
|
if (list_empty(&lip->li_cil))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* li_seq is written on the first commit of a log item to record the
|
||||||
|
* first checkpoint it is written to. Hence if it is different to the
|
||||||
|
* current sequence, we're in a new checkpoint.
|
||||||
|
*/
|
||||||
|
return lip->li_seq == READ_ONCE(cil->xc_current_sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
xfs_log_item_in_current_chkpt(
|
||||||
|
struct xfs_log_item *lip)
|
||||||
|
{
|
||||||
|
return xlog_item_in_current_chkpt(lip->li_log->l_cilp, lip);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unavoidable forward declaration - xlog_cil_push_work() calls
|
* Unavoidable forward declaration - xlog_cil_push_work() calls
|
||||||
* xlog_cil_ctx_alloc() itself.
|
* xlog_cil_ctx_alloc() itself.
|
||||||
|
@ -934,6 +966,40 @@ xlog_cil_build_trans_hdr(
|
||||||
tic->t_curr_res -= lvhdr->lv_bytes;
|
tic->t_curr_res -= lvhdr->lv_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pull all the log vectors off the items in the CIL, and remove the items from
|
||||||
|
* the CIL. We don't need the CIL lock here because it's only needed on the
|
||||||
|
* transaction commit side which is currently locked out by the flush lock.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
xlog_cil_build_lv_chain(
|
||||||
|
struct xfs_cil *cil,
|
||||||
|
struct xfs_cil_ctx *ctx,
|
||||||
|
uint32_t *num_iovecs,
|
||||||
|
uint32_t *num_bytes)
|
||||||
|
{
|
||||||
|
struct xfs_log_vec *lv = NULL;
|
||||||
|
|
||||||
|
while (!list_empty(&cil->xc_cil)) {
|
||||||
|
struct xfs_log_item *item;
|
||||||
|
|
||||||
|
item = list_first_entry(&cil->xc_cil,
|
||||||
|
struct xfs_log_item, li_cil);
|
||||||
|
list_del_init(&item->li_cil);
|
||||||
|
if (!ctx->lv_chain)
|
||||||
|
ctx->lv_chain = item->li_lv;
|
||||||
|
else
|
||||||
|
lv->lv_next = item->li_lv;
|
||||||
|
lv = item->li_lv;
|
||||||
|
item->li_lv = NULL;
|
||||||
|
*num_iovecs += lv->lv_niovecs;
|
||||||
|
|
||||||
|
/* we don't write ordered log vectors */
|
||||||
|
if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED)
|
||||||
|
*num_bytes += lv->lv_bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Push the Committed Item List to the log.
|
* Push the Committed Item List to the log.
|
||||||
*
|
*
|
||||||
|
@ -956,7 +1022,6 @@ xlog_cil_push_work(
|
||||||
container_of(work, struct xfs_cil_ctx, push_work);
|
container_of(work, struct xfs_cil_ctx, push_work);
|
||||||
struct xfs_cil *cil = ctx->cil;
|
struct xfs_cil *cil = ctx->cil;
|
||||||
struct xlog *log = cil->xc_log;
|
struct xlog *log = cil->xc_log;
|
||||||
struct xfs_log_vec *lv;
|
|
||||||
struct xfs_cil_ctx *new_ctx;
|
struct xfs_cil_ctx *new_ctx;
|
||||||
int num_iovecs = 0;
|
int num_iovecs = 0;
|
||||||
int num_bytes = 0;
|
int num_bytes = 0;
|
||||||
|
@ -1033,31 +1098,7 @@ xlog_cil_push_work(
|
||||||
list_add(&ctx->committing, &cil->xc_committing);
|
list_add(&ctx->committing, &cil->xc_committing);
|
||||||
spin_unlock(&cil->xc_push_lock);
|
spin_unlock(&cil->xc_push_lock);
|
||||||
|
|
||||||
/*
|
xlog_cil_build_lv_chain(cil, ctx, &num_iovecs, &num_bytes);
|
||||||
* Pull all the log vectors off the items in the CIL, and remove the
|
|
||||||
* items from the CIL. We don't need the CIL lock here because it's only
|
|
||||||
* needed on the transaction commit side which is currently locked out
|
|
||||||
* by the flush lock.
|
|
||||||
*/
|
|
||||||
lv = NULL;
|
|
||||||
while (!list_empty(&cil->xc_cil)) {
|
|
||||||
struct xfs_log_item *item;
|
|
||||||
|
|
||||||
item = list_first_entry(&cil->xc_cil,
|
|
||||||
struct xfs_log_item, li_cil);
|
|
||||||
list_del_init(&item->li_cil);
|
|
||||||
if (!ctx->lv_chain)
|
|
||||||
ctx->lv_chain = item->li_lv;
|
|
||||||
else
|
|
||||||
lv->lv_next = item->li_lv;
|
|
||||||
lv = item->li_lv;
|
|
||||||
item->li_lv = NULL;
|
|
||||||
num_iovecs += lv->lv_niovecs;
|
|
||||||
|
|
||||||
/* we don't write ordered log vectors */
|
|
||||||
if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED)
|
|
||||||
num_bytes += lv->lv_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Switch the contexts so we can drop the context lock and move out
|
* Switch the contexts so we can drop the context lock and move out
|
||||||
|
@ -1508,32 +1549,6 @@ out_shutdown:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if the current log item was first committed in this sequence.
|
|
||||||
* We can't rely on just the log item being in the CIL, we have to check
|
|
||||||
* the recorded commit sequence number.
|
|
||||||
*
|
|
||||||
* Note: for this to be used in a non-racy manner, it has to be called with
|
|
||||||
* CIL flushing locked out. As a result, it should only be used during the
|
|
||||||
* transaction commit process when deciding what to format into the item.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
xfs_log_item_in_current_chkpt(
|
|
||||||
struct xfs_log_item *lip)
|
|
||||||
{
|
|
||||||
struct xfs_cil *cil = lip->li_log->l_cilp;
|
|
||||||
|
|
||||||
if (list_empty(&lip->li_cil))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* li_seq is written on the first commit of a log item to record the
|
|
||||||
* first checkpoint it is written to. Hence if it is different to the
|
|
||||||
* current sequence, we're in a new checkpoint.
|
|
||||||
*/
|
|
||||||
return lip->li_seq == READ_ONCE(cil->xc_current_sequence);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Perform initial CIL structure initialisation.
|
* Perform initial CIL structure initialisation.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue