Commit d80fc291 authored by Dave Chinner's avatar Dave Chinner Committed by Dave Chinner

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: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarChandan Babu R <chandan.babu@oracle.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent c5141320
...@@ -958,7 +958,8 @@ xlog_write_unmount_record( ...@@ -958,7 +958,8 @@ xlog_write_unmount_record(
/* account for space used by record data */ /* account for space used by record data */
ticket->t_curr_res -= sizeof(unmount_rec); 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( ...@@ -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 * static xlog_op_header_t *
xlog_write_setup_ophdr( xlog_write_setup_ophdr(
struct xlog_op_header *ophdr, struct xlog_op_header *ophdr,
...@@ -2388,13 +2363,14 @@ xlog_write( ...@@ -2388,13 +2363,14 @@ xlog_write(
struct xfs_cil_ctx *ctx, struct xfs_cil_ctx *ctx,
struct xfs_log_vec *log_vector, struct xfs_log_vec *log_vector,
struct xlog_ticket *ticket, struct xlog_ticket *ticket,
uint optype) uint optype,
uint32_t len)
{ {
struct xlog_in_core *iclog = NULL; struct xlog_in_core *iclog = NULL;
struct xfs_log_vec *lv = log_vector; struct xfs_log_vec *lv = log_vector;
struct xfs_log_iovec *vecp = lv->lv_iovecp; struct xfs_log_iovec *vecp = lv->lv_iovecp;
int index = 0; int index = 0;
int len;
int partial_copy = 0; int partial_copy = 0;
int partial_copy_len = 0; int partial_copy_len = 0;
int contwr = 0; int contwr = 0;
...@@ -2409,7 +2385,6 @@ xlog_write( ...@@ -2409,7 +2385,6 @@ xlog_write(
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR); 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)) { while (lv && (!lv->lv_niovecs || index < lv->lv_niovecs)) {
void *ptr; void *ptr;
int log_offset; int log_offset;
......
...@@ -825,7 +825,8 @@ xlog_cil_order_write( ...@@ -825,7 +825,8 @@ xlog_cil_order_write(
static int static int
xlog_cil_write_chain( xlog_cil_write_chain(
struct xfs_cil_ctx *ctx, 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; struct xlog *log = ctx->cil->xc_log;
int error; int error;
...@@ -833,7 +834,8 @@ xlog_cil_write_chain( ...@@ -833,7 +834,8 @@ xlog_cil_write_chain(
error = xlog_cil_order_write(ctx->cil, ctx->sequence, _START_RECORD); error = xlog_cil_order_write(ctx->cil, ctx->sequence, _START_RECORD);
if (error) if (error)
return 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( ...@@ -872,7 +874,8 @@ xlog_cil_write_commit_record(
/* account for space used by record data */ /* account for space used by record data */
ctx->ticket->t_curr_res -= reg.i_len; 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) if (error)
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR); xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
return error; return error;
...@@ -935,11 +938,12 @@ xlog_cil_build_trans_hdr( ...@@ -935,11 +938,12 @@ xlog_cil_build_trans_hdr(
sizeof(struct xfs_trans_header); sizeof(struct xfs_trans_header);
hdr->lhdr[1].i_type = XLOG_REG_TYPE_TRANSHDR; 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_niovecs = 2;
lvhdr->lv_iovecp = &hdr->lhdr[0]; 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; lvhdr->lv_next = ctx->lv_chain;
tic->t_curr_res -= lvhdr->lv_bytes;
} }
/* /*
...@@ -966,7 +970,8 @@ xlog_cil_push_work( ...@@ -966,7 +970,8 @@ xlog_cil_push_work(
struct xlog *log = cil->xc_log; struct xlog *log = cil->xc_log;
struct xfs_log_vec *lv; struct xfs_log_vec *lv;
struct xfs_cil_ctx *new_ctx; struct xfs_cil_ctx *new_ctx;
int num_iovecs; int num_iovecs = 0;
int num_bytes = 0;
int error = 0; int error = 0;
struct xlog_cil_trans_hdr thdr; struct xlog_cil_trans_hdr thdr;
struct xfs_log_vec lvhdr = { NULL }; struct xfs_log_vec lvhdr = { NULL };
...@@ -1047,7 +1052,6 @@ xlog_cil_push_work( ...@@ -1047,7 +1052,6 @@ xlog_cil_push_work(
* by the flush lock. * by the flush lock.
*/ */
lv = NULL; lv = NULL;
num_iovecs = 0;
while (!list_empty(&cil->xc_cil)) { while (!list_empty(&cil->xc_cil)) {
struct xfs_log_item *item; struct xfs_log_item *item;
...@@ -1061,6 +1065,10 @@ xlog_cil_push_work( ...@@ -1061,6 +1065,10 @@ xlog_cil_push_work(
lv = item->li_lv; lv = item->li_lv;
item->li_lv = NULL; item->li_lv = NULL;
num_iovecs += lv->lv_niovecs; 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( ...@@ -1099,8 +1107,9 @@ xlog_cil_push_work(
* transaction header here as it is not accounted for in xlog_write(). * transaction header here as it is not accounted for in xlog_write().
*/ */
xlog_cil_build_trans_hdr(ctx, &thdr, &lvhdr, num_iovecs); 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) if (error)
goto out_abort_free_ticket; goto out_abort_free_ticket;
......
...@@ -503,7 +503,7 @@ void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *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 *); void xlog_print_trans(struct xfs_trans *);
int xlog_write(struct xlog *log, struct xfs_cil_ctx *ctx, int xlog_write(struct xlog *log, struct xfs_cil_ctx *ctx,
struct xfs_log_vec *log_vector, struct xlog_ticket *tic, 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_ungrant(struct xlog *log, struct xlog_ticket *ticket);
void xfs_log_ticket_regrant(struct xlog *log, struct xlog_ticket *ticket); void xfs_log_ticket_regrant(struct xlog *log, struct xlog_ticket *ticket);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment