xfs: pass lv chain length into xlog_write()
The caller of xlog_write() usually has a close accounting of the aggregated vector length contained in the log vector chain passed to xlog_write(). There is no need to iterate the chain to calculate he length of the data in xlog_write_calculate_len() if the caller is already iterating that chain to build it. Passing in the vector length avoids doing an extra chain iteration, which can be a significant amount of work given that large CIL commits can have hundreds of thousands of vectors attached to the chain. 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: Chandan Babu R <chandan.babu@oracle.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
c5141320c4
commit
d80fc2914f
|
@ -958,7 +958,8 @@ xlog_write_unmount_record(
|
|||
/* account for space used by record data */
|
||||
ticket->t_curr_res -= sizeof(unmount_rec);
|
||||
|
||||
return xlog_write(log, NULL, &vec, ticket, XLOG_UNMOUNT_TRANS);
|
||||
return xlog_write(log, NULL, &vec, ticket, XLOG_UNMOUNT_TRANS,
|
||||
reg.i_len);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2209,32 +2210,6 @@ xlog_print_trans(
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the potential space needed by the log vector. All regions contain
|
||||
* their own opheaders and they are accounted for in region space so we don't
|
||||
* need to add them to the vector length here.
|
||||
*/
|
||||
static int
|
||||
xlog_write_calc_vec_length(
|
||||
struct xlog_ticket *ticket,
|
||||
struct xfs_log_vec *log_vector,
|
||||
uint optype)
|
||||
{
|
||||
struct xfs_log_vec *lv;
|
||||
int len = 0;
|
||||
int i;
|
||||
|
||||
for (lv = log_vector; lv; lv = lv->lv_next) {
|
||||
/* we don't write ordered log vectors */
|
||||
if (lv->lv_buf_len == XFS_LOG_VEC_ORDERED)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < lv->lv_niovecs; i++)
|
||||
len += lv->lv_iovecp[i].i_len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static xlog_op_header_t *
|
||||
xlog_write_setup_ophdr(
|
||||
struct xlog_op_header *ophdr,
|
||||
|
@ -2388,13 +2363,14 @@ xlog_write(
|
|||
struct xfs_cil_ctx *ctx,
|
||||
struct xfs_log_vec *log_vector,
|
||||
struct xlog_ticket *ticket,
|
||||
uint optype)
|
||||
uint optype,
|
||||
uint32_t len)
|
||||
|
||||
{
|
||||
struct xlog_in_core *iclog = NULL;
|
||||
struct xfs_log_vec *lv = log_vector;
|
||||
struct xfs_log_iovec *vecp = lv->lv_iovecp;
|
||||
int index = 0;
|
||||
int len;
|
||||
int partial_copy = 0;
|
||||
int partial_copy_len = 0;
|
||||
int contwr = 0;
|
||||
|
@ -2409,7 +2385,6 @@ xlog_write(
|
|||
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
|
||||
}
|
||||
|
||||
len = xlog_write_calc_vec_length(ticket, log_vector, optype);
|
||||
while (lv && (!lv->lv_niovecs || index < lv->lv_niovecs)) {
|
||||
void *ptr;
|
||||
int log_offset;
|
||||
|
|
|
@ -825,7 +825,8 @@ restart:
|
|||
static int
|
||||
xlog_cil_write_chain(
|
||||
struct xfs_cil_ctx *ctx,
|
||||
struct xfs_log_vec *chain)
|
||||
struct xfs_log_vec *chain,
|
||||
uint32_t chain_len)
|
||||
{
|
||||
struct xlog *log = ctx->cil->xc_log;
|
||||
int error;
|
||||
|
@ -833,7 +834,8 @@ xlog_cil_write_chain(
|
|||
error = xlog_cil_order_write(ctx->cil, ctx->sequence, _START_RECORD);
|
||||
if (error)
|
||||
return error;
|
||||
return xlog_write(log, ctx, chain, ctx->ticket, XLOG_START_TRANS);
|
||||
return xlog_write(log, ctx, chain, ctx->ticket, XLOG_START_TRANS,
|
||||
chain_len);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -872,7 +874,8 @@ xlog_cil_write_commit_record(
|
|||
|
||||
/* account for space used by record data */
|
||||
ctx->ticket->t_curr_res -= reg.i_len;
|
||||
error = xlog_write(log, ctx, &vec, ctx->ticket, XLOG_COMMIT_TRANS);
|
||||
error = xlog_write(log, ctx, &vec, ctx->ticket, XLOG_COMMIT_TRANS,
|
||||
reg.i_len);
|
||||
if (error)
|
||||
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
|
||||
return error;
|
||||
|
@ -935,11 +938,12 @@ xlog_cil_build_trans_hdr(
|
|||
sizeof(struct xfs_trans_header);
|
||||
hdr->lhdr[1].i_type = XLOG_REG_TYPE_TRANSHDR;
|
||||
|
||||
tic->t_curr_res -= hdr->lhdr[0].i_len + hdr->lhdr[1].i_len;
|
||||
|
||||
lvhdr->lv_niovecs = 2;
|
||||
lvhdr->lv_iovecp = &hdr->lhdr[0];
|
||||
lvhdr->lv_bytes = hdr->lhdr[0].i_len + hdr->lhdr[1].i_len;
|
||||
lvhdr->lv_next = ctx->lv_chain;
|
||||
|
||||
tic->t_curr_res -= lvhdr->lv_bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -966,7 +970,8 @@ xlog_cil_push_work(
|
|||
struct xlog *log = cil->xc_log;
|
||||
struct xfs_log_vec *lv;
|
||||
struct xfs_cil_ctx *new_ctx;
|
||||
int num_iovecs;
|
||||
int num_iovecs = 0;
|
||||
int num_bytes = 0;
|
||||
int error = 0;
|
||||
struct xlog_cil_trans_hdr thdr;
|
||||
struct xfs_log_vec lvhdr = { NULL };
|
||||
|
@ -1047,7 +1052,6 @@ xlog_cil_push_work(
|
|||
* by the flush lock.
|
||||
*/
|
||||
lv = NULL;
|
||||
num_iovecs = 0;
|
||||
while (!list_empty(&cil->xc_cil)) {
|
||||
struct xfs_log_item *item;
|
||||
|
||||
|
@ -1061,6 +1065,10 @@ xlog_cil_push_work(
|
|||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1099,8 +1107,9 @@ xlog_cil_push_work(
|
|||
* transaction header here as it is not accounted for in xlog_write().
|
||||
*/
|
||||
xlog_cil_build_trans_hdr(ctx, &thdr, &lvhdr, num_iovecs);
|
||||
num_bytes += lvhdr.lv_bytes;
|
||||
|
||||
error = xlog_cil_write_chain(ctx, &lvhdr);
|
||||
error = xlog_cil_write_chain(ctx, &lvhdr, num_bytes);
|
||||
if (error)
|
||||
goto out_abort_free_ticket;
|
||||
|
||||
|
|
|
@ -503,7 +503,7 @@ void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket);
|
|||
void xlog_print_trans(struct xfs_trans *);
|
||||
int xlog_write(struct xlog *log, struct xfs_cil_ctx *ctx,
|
||||
struct xfs_log_vec *log_vector, struct xlog_ticket *tic,
|
||||
uint optype);
|
||||
uint optype, uint32_t len);
|
||||
void xfs_log_ticket_ungrant(struct xlog *log, struct xlog_ticket *ticket);
|
||||
void xfs_log_ticket_regrant(struct xlog *log, struct xlog_ticket *ticket);
|
||||
|
||||
|
|
Loading…
Reference in New Issue