summaryrefslogtreecommitdiff
path: root/fs/xfs/xfs_log_cil.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2022-04-21 10:35:19 +1000
committerDave Chinner <david@fromorbit.com>2022-04-21 10:35:19 +1000
commitd80fc2914f9125a723d9af7038b1592fa8d1ea96 (patch)
tree72bb8596ab7cbe80add90831a9c8dfac6d9a6099 /fs/xfs/xfs_log_cil.c
parentc5141320c42b08b99b7c4b250ac9675d7c7ed3a7 (diff)
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>
Diffstat (limited to 'fs/xfs/xfs_log_cil.c')
-rw-r--r--fs/xfs/xfs_log_cil.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index 5ccbb6bd4655..dad2b527c3ff 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -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;