Skip to content

Commit d80fc29

Browse files
dgchinnerdchinner
authored andcommitted
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>
1 parent c514132 commit d80fc29

3 files changed

Lines changed: 23 additions & 39 deletions

File tree

fs/xfs/xfs_log.c

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,8 @@ xlog_write_unmount_record(
958958
/* account for space used by record data */
959959
ticket->t_curr_res -= sizeof(unmount_rec);
960960

961-
return xlog_write(log, NULL, &vec, ticket, XLOG_UNMOUNT_TRANS);
961+
return xlog_write(log, NULL, &vec, ticket, XLOG_UNMOUNT_TRANS,
962+
reg.i_len);
962963
}
963964

964965
/*
@@ -2209,32 +2210,6 @@ xlog_print_trans(
22092210
}
22102211
}
22112212

2212-
/*
2213-
* Calculate the potential space needed by the log vector. All regions contain
2214-
* their own opheaders and they are accounted for in region space so we don't
2215-
* need to add them to the vector length here.
2216-
*/
2217-
static int
2218-
xlog_write_calc_vec_length(
2219-
struct xlog_ticket *ticket,
2220-
struct xfs_log_vec *log_vector,
2221-
uint optype)
2222-
{
2223-
struct xfs_log_vec *lv;
2224-
int len = 0;
2225-
int i;
2226-
2227-
for (lv = log_vector; lv; lv = lv->lv_next) {
2228-
/* we don't write ordered log vectors */
2229-
if (lv->lv_buf_len == XFS_LOG_VEC_ORDERED)
2230-
continue;
2231-
2232-
for (i = 0; i < lv->lv_niovecs; i++)
2233-
len += lv->lv_iovecp[i].i_len;
2234-
}
2235-
return len;
2236-
}
2237-
22382213
static xlog_op_header_t *
22392214
xlog_write_setup_ophdr(
22402215
struct xlog_op_header *ophdr,
@@ -2388,13 +2363,14 @@ xlog_write(
23882363
struct xfs_cil_ctx *ctx,
23892364
struct xfs_log_vec *log_vector,
23902365
struct xlog_ticket *ticket,
2391-
uint optype)
2366+
uint optype,
2367+
uint32_t len)
2368+
23922369
{
23932370
struct xlog_in_core *iclog = NULL;
23942371
struct xfs_log_vec *lv = log_vector;
23952372
struct xfs_log_iovec *vecp = lv->lv_iovecp;
23962373
int index = 0;
2397-
int len;
23982374
int partial_copy = 0;
23992375
int partial_copy_len = 0;
24002376
int contwr = 0;
@@ -2409,7 +2385,6 @@ xlog_write(
24092385
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
24102386
}
24112387

2412-
len = xlog_write_calc_vec_length(ticket, log_vector, optype);
24132388
while (lv && (!lv->lv_niovecs || index < lv->lv_niovecs)) {
24142389
void *ptr;
24152390
int log_offset;

fs/xfs/xfs_log_cil.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -825,15 +825,17 @@ xlog_cil_order_write(
825825
static int
826826
xlog_cil_write_chain(
827827
struct xfs_cil_ctx *ctx,
828-
struct xfs_log_vec *chain)
828+
struct xfs_log_vec *chain,
829+
uint32_t chain_len)
829830
{
830831
struct xlog *log = ctx->cil->xc_log;
831832
int error;
832833

833834
error = xlog_cil_order_write(ctx->cil, ctx->sequence, _START_RECORD);
834835
if (error)
835836
return error;
836-
return xlog_write(log, ctx, chain, ctx->ticket, XLOG_START_TRANS);
837+
return xlog_write(log, ctx, chain, ctx->ticket, XLOG_START_TRANS,
838+
chain_len);
837839
}
838840

839841
/*
@@ -872,7 +874,8 @@ xlog_cil_write_commit_record(
872874

873875
/* account for space used by record data */
874876
ctx->ticket->t_curr_res -= reg.i_len;
875-
error = xlog_write(log, ctx, &vec, ctx->ticket, XLOG_COMMIT_TRANS);
877+
error = xlog_write(log, ctx, &vec, ctx->ticket, XLOG_COMMIT_TRANS,
878+
reg.i_len);
876879
if (error)
877880
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
878881
return error;
@@ -935,11 +938,12 @@ xlog_cil_build_trans_hdr(
935938
sizeof(struct xfs_trans_header);
936939
hdr->lhdr[1].i_type = XLOG_REG_TYPE_TRANSHDR;
937940

938-
tic->t_curr_res -= hdr->lhdr[0].i_len + hdr->lhdr[1].i_len;
939-
940941
lvhdr->lv_niovecs = 2;
941942
lvhdr->lv_iovecp = &hdr->lhdr[0];
943+
lvhdr->lv_bytes = hdr->lhdr[0].i_len + hdr->lhdr[1].i_len;
942944
lvhdr->lv_next = ctx->lv_chain;
945+
946+
tic->t_curr_res -= lvhdr->lv_bytes;
943947
}
944948

945949
/*
@@ -966,7 +970,8 @@ xlog_cil_push_work(
966970
struct xlog *log = cil->xc_log;
967971
struct xfs_log_vec *lv;
968972
struct xfs_cil_ctx *new_ctx;
969-
int num_iovecs;
973+
int num_iovecs = 0;
974+
int num_bytes = 0;
970975
int error = 0;
971976
struct xlog_cil_trans_hdr thdr;
972977
struct xfs_log_vec lvhdr = { NULL };
@@ -1047,7 +1052,6 @@ xlog_cil_push_work(
10471052
* by the flush lock.
10481053
*/
10491054
lv = NULL;
1050-
num_iovecs = 0;
10511055
while (!list_empty(&cil->xc_cil)) {
10521056
struct xfs_log_item *item;
10531057

@@ -1061,6 +1065,10 @@ xlog_cil_push_work(
10611065
lv = item->li_lv;
10621066
item->li_lv = NULL;
10631067
num_iovecs += lv->lv_niovecs;
1068+
1069+
/* we don't write ordered log vectors */
1070+
if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED)
1071+
num_bytes += lv->lv_bytes;
10641072
}
10651073

10661074
/*
@@ -1099,8 +1107,9 @@ xlog_cil_push_work(
10991107
* transaction header here as it is not accounted for in xlog_write().
11001108
*/
11011109
xlog_cil_build_trans_hdr(ctx, &thdr, &lvhdr, num_iovecs);
1110+
num_bytes += lvhdr.lv_bytes;
11021111

1103-
error = xlog_cil_write_chain(ctx, &lvhdr);
1112+
error = xlog_cil_write_chain(ctx, &lvhdr, num_bytes);
11041113
if (error)
11051114
goto out_abort_free_ticket;
11061115

fs/xfs/xfs_log_priv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket);
503503
void xlog_print_trans(struct xfs_trans *);
504504
int xlog_write(struct xlog *log, struct xfs_cil_ctx *ctx,
505505
struct xfs_log_vec *log_vector, struct xlog_ticket *tic,
506-
uint optype);
506+
uint optype, uint32_t len);
507507
void xfs_log_ticket_ungrant(struct xlog *log, struct xlog_ticket *ticket);
508508
void xfs_log_ticket_regrant(struct xlog *log, struct xlog_ticket *ticket);
509509

0 commit comments

Comments
 (0)