Skip to content

Commit 1692485

Browse files
dgchinnerdchinner
authored andcommitted
xfs: convert log vector chain to use list heads
Because the next change is going to require sorting log vectors, and that requires arbitrary rearrangement of the list which cannot be done easily with a single linked list. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
1 parent c0fb476 commit 1692485

6 files changed

Lines changed: 43 additions & 35 deletions

File tree

fs/xfs/xfs_log.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,8 @@ xlog_write_unmount_record(
944944
.lv_niovecs = 1,
945945
.lv_iovecp = &reg,
946946
};
947+
LIST_HEAD(lv_chain);
948+
list_add(&vec.lv_list, &lv_chain);
947949

948950
BUILD_BUG_ON((sizeof(struct xlog_op_header) +
949951
sizeof(struct xfs_unmount_log_format)) !=
@@ -952,7 +954,7 @@ xlog_write_unmount_record(
952954
/* account for space used by record data */
953955
ticket->t_curr_res -= sizeof(unmount_rec);
954956

955-
return xlog_write(log, NULL, &vec, ticket, reg.i_len);
957+
return xlog_write(log, NULL, &lv_chain, ticket, reg.i_len);
956958
}
957959

958960
/*
@@ -2471,13 +2473,13 @@ int
24712473
xlog_write(
24722474
struct xlog *log,
24732475
struct xfs_cil_ctx *ctx,
2474-
struct xfs_log_vec *log_vector,
2476+
struct list_head *lv_chain,
24752477
struct xlog_ticket *ticket,
24762478
uint32_t len)
24772479

24782480
{
24792481
struct xlog_in_core *iclog = NULL;
2480-
struct xfs_log_vec *lv = log_vector;
2482+
struct xfs_log_vec *lv;
24812483
uint32_t record_cnt = 0;
24822484
uint32_t data_cnt = 0;
24832485
int error = 0;
@@ -2505,7 +2507,7 @@ xlog_write(
25052507
if (ctx)
25062508
xlog_cil_set_ctx_write_state(ctx, iclog);
25072509

2508-
while (lv) {
2510+
list_for_each_entry(lv, lv_chain, lv_list) {
25092511
/*
25102512
* If the entire log vec does not fit in the iclog, punt it to
25112513
* the partial copy loop which can handle this case.
@@ -2526,7 +2528,6 @@ xlog_write(
25262528
xlog_write_full(lv, ticket, iclog, &log_offset,
25272529
&len, &record_cnt, &data_cnt);
25282530
}
2529-
lv = lv->lv_next;
25302531
}
25312532
ASSERT(len == 0);
25322533

fs/xfs/xfs_log.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
struct xfs_cil_ctx;
1010

1111
struct xfs_log_vec {
12-
struct xfs_log_vec *lv_next; /* next lv in build list */
12+
struct list_head lv_list; /* CIL lv chain ptrs */
1313
int lv_niovecs; /* number of iovecs in lv */
1414
struct xfs_log_iovec *lv_iovecp; /* iovec array */
1515
struct xfs_log_item *lv_item; /* owner */

fs/xfs/xfs_log_cil.c

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ xlog_cil_ctx_alloc(void)
105105
INIT_LIST_HEAD(&ctx->committing);
106106
INIT_LIST_HEAD(&ctx->busy_extents);
107107
INIT_LIST_HEAD(&ctx->log_items);
108+
INIT_LIST_HEAD(&ctx->lv_chain);
108109
INIT_WORK(&ctx->push_work, xlog_cil_push_work);
109110
return ctx;
110111
}
@@ -338,6 +339,7 @@ xlog_cil_alloc_shadow_bufs(
338339

339340
memset(lv, 0, xlog_cil_iovec_space(niovecs));
340341

342+
INIT_LIST_HEAD(&lv->lv_list);
341343
lv->lv_item = lip;
342344
lv->lv_size = buf_size;
343345
if (ordered)
@@ -353,7 +355,6 @@ xlog_cil_alloc_shadow_bufs(
353355
else
354356
lv->lv_buf_len = 0;
355357
lv->lv_bytes = 0;
356-
lv->lv_next = NULL;
357358
}
358359

359360
/* Ensure the lv is set up according to ->iop_size */
@@ -480,7 +481,6 @@ xlog_cil_insert_format_items(
480481
if (lip->li_lv && shadow->lv_size <= lip->li_lv->lv_size) {
481482
/* same or smaller, optimise common overwrite case */
482483
lv = lip->li_lv;
483-
lv->lv_next = NULL;
484484

485485
if (ordered)
486486
goto insert;
@@ -685,14 +685,14 @@ xlog_cil_insert_items(
685685

686686
static void
687687
xlog_cil_free_logvec(
688-
struct xfs_log_vec *log_vector)
688+
struct list_head *lv_chain)
689689
{
690690
struct xfs_log_vec *lv;
691691

692-
for (lv = log_vector; lv; ) {
693-
struct xfs_log_vec *next = lv->lv_next;
692+
while (!list_empty(lv_chain)) {
693+
lv = list_first_entry(lv_chain, struct xfs_log_vec, lv_list);
694+
list_del_init(&lv->lv_list);
694695
kmem_free(lv);
695-
lv = next;
696696
}
697697
}
698698

@@ -792,7 +792,7 @@ xlog_cil_committed(
792792
spin_unlock(&ctx->cil->xc_push_lock);
793793
}
794794

795-
xfs_trans_committed_bulk(ctx->cil->xc_log->l_ailp, ctx->lv_chain,
795+
xfs_trans_committed_bulk(ctx->cil->xc_log->l_ailp, &ctx->lv_chain,
796796
ctx->start_lsn, abort);
797797

798798
xfs_extent_busy_sort(&ctx->busy_extents);
@@ -803,7 +803,7 @@ xlog_cil_committed(
803803
list_del(&ctx->committing);
804804
spin_unlock(&ctx->cil->xc_push_lock);
805805

806-
xlog_cil_free_logvec(ctx->lv_chain);
806+
xlog_cil_free_logvec(&ctx->lv_chain);
807807

808808
if (!list_empty(&ctx->busy_extents))
809809
xlog_discard_busy_extents(mp, ctx);
@@ -962,7 +962,6 @@ xlog_cil_order_write(
962962
static int
963963
xlog_cil_write_chain(
964964
struct xfs_cil_ctx *ctx,
965-
struct xfs_log_vec *chain,
966965
uint32_t chain_len)
967966
{
968967
struct xlog *log = ctx->cil->xc_log;
@@ -971,7 +970,7 @@ xlog_cil_write_chain(
971970
error = xlog_cil_order_write(ctx->cil, ctx->sequence, _START_RECORD);
972971
if (error)
973972
return error;
974-
return xlog_write(log, ctx, chain, ctx->ticket, chain_len);
973+
return xlog_write(log, ctx, &ctx->lv_chain, ctx->ticket, chain_len);
975974
}
976975

977976
/*
@@ -1000,6 +999,8 @@ xlog_cil_write_commit_record(
1000999
.lv_iovecp = &reg,
10011000
};
10021001
int error;
1002+
LIST_HEAD(lv_chain);
1003+
list_add(&vec.lv_list, &lv_chain);
10031004

10041005
if (xlog_is_shutdown(log))
10051006
return -EIO;
@@ -1010,7 +1011,7 @@ xlog_cil_write_commit_record(
10101011

10111012
/* account for space used by record data */
10121013
ctx->ticket->t_curr_res -= reg.i_len;
1013-
error = xlog_write(log, ctx, &vec, ctx->ticket, reg.i_len);
1014+
error = xlog_write(log, ctx, &lv_chain, ctx->ticket, reg.i_len);
10141015
if (error)
10151016
xlog_force_shutdown(log, SHUTDOWN_LOG_IO_ERROR);
10161017
return error;
@@ -1076,7 +1077,6 @@ xlog_cil_build_trans_hdr(
10761077
lvhdr->lv_niovecs = 2;
10771078
lvhdr->lv_iovecp = &hdr->lhdr[0];
10781079
lvhdr->lv_bytes = hdr->lhdr[0].i_len + hdr->lhdr[1].i_len;
1079-
lvhdr->lv_next = ctx->lv_chain;
10801080

10811081
tic->t_curr_res -= lvhdr->lv_bytes;
10821082
}
@@ -1117,12 +1117,11 @@ xlog_cil_build_lv_chain(
11171117
uint32_t *num_iovecs,
11181118
uint32_t *num_bytes)
11191119
{
1120-
struct xfs_log_vec *lv = NULL;
1121-
11221120
list_sort(NULL, &ctx->log_items, xlog_cil_order_cmp);
11231121

11241122
while (!list_empty(&ctx->log_items)) {
11251123
struct xfs_log_item *item;
1124+
struct xfs_log_vec *lv;
11261125

11271126
item = list_first_entry(&ctx->log_items,
11281127
struct xfs_log_item, li_cil);
@@ -1133,19 +1132,17 @@ xlog_cil_build_lv_chain(
11331132
continue;
11341133
}
11351134

1136-
list_del_init(&item->li_cil);
1137-
item->li_order_id = 0;
1138-
if (!ctx->lv_chain)
1139-
ctx->lv_chain = item->li_lv;
1140-
else
1141-
lv->lv_next = item->li_lv;
11421135
lv = item->li_lv;
1143-
item->li_lv = NULL;
1144-
*num_iovecs += lv->lv_niovecs;
11451136

11461137
/* we don't write ordered log vectors */
11471138
if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED)
11481139
*num_bytes += lv->lv_bytes;
1140+
*num_iovecs += lv->lv_niovecs;
1141+
list_add_tail(&lv->lv_list, &ctx->lv_chain);
1142+
1143+
list_del_init(&item->li_cil);
1144+
item->li_order_id = 0;
1145+
item->li_lv = NULL;
11491146
}
11501147
}
11511148

@@ -1189,7 +1186,7 @@ xlog_cil_push_work(
11891186
int num_bytes = 0;
11901187
int error = 0;
11911188
struct xlog_cil_trans_hdr thdr;
1192-
struct xfs_log_vec lvhdr = { NULL };
1189+
struct xfs_log_vec lvhdr = {};
11931190
xfs_csn_t push_seq;
11941191
bool push_commit_stable;
11951192
LIST_HEAD (whiteouts);
@@ -1299,11 +1296,20 @@ xlog_cil_push_work(
12991296
* Build a checkpoint transaction header and write it to the log to
13001297
* begin the transaction. We need to account for the space used by the
13011298
* transaction header here as it is not accounted for in xlog_write().
1299+
* Add the lvhdr to the head of the lv chain we pass to xlog_write() so
1300+
* it gets written into the iclog first.
13021301
*/
13031302
xlog_cil_build_trans_hdr(ctx, &thdr, &lvhdr, num_iovecs);
13041303
num_bytes += lvhdr.lv_bytes;
1304+
list_add(&lvhdr.lv_list, &ctx->lv_chain);
13051305

1306-
error = xlog_cil_write_chain(ctx, &lvhdr, num_bytes);
1306+
/*
1307+
* Take the lvhdr back off the lv_chain immediately after calling
1308+
* xlog_cil_write_chain() as it should not be passed to log IO
1309+
* completion.
1310+
*/
1311+
error = xlog_cil_write_chain(ctx, num_bytes);
1312+
list_del(&lvhdr.lv_list);
13071313
if (error)
13081314
goto out_abort_free_ticket;
13091315

fs/xfs/xfs_log_priv.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ struct xfs_cil_ctx {
225225
atomic_t space_used; /* aggregate size of regions */
226226
struct list_head busy_extents; /* busy extents in chkpt */
227227
struct list_head log_items; /* log items in chkpt */
228-
struct xfs_log_vec *lv_chain; /* logvecs being pushed */
228+
struct list_head lv_chain; /* logvecs being pushed */
229229
struct list_head iclog_entry;
230230
struct list_head committing; /* ctx committing list */
231231
struct work_struct discard_endio_work;
@@ -508,7 +508,7 @@ struct xlog_ticket *xlog_ticket_alloc(struct xlog *log, int unit_bytes,
508508
void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket);
509509
void xlog_print_trans(struct xfs_trans *);
510510
int xlog_write(struct xlog *log, struct xfs_cil_ctx *ctx,
511-
struct xfs_log_vec *log_vector, struct xlog_ticket *tic,
511+
struct list_head *lv_chain, struct xlog_ticket *tic,
512512
uint32_t len);
513513
void xfs_log_ticket_ungrant(struct xlog *log, struct xlog_ticket *ticket);
514514
void xfs_log_ticket_regrant(struct xlog *log, struct xlog_ticket *ticket);

fs/xfs/xfs_trans.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,7 @@ xfs_log_item_batch_insert(
760760
void
761761
xfs_trans_committed_bulk(
762762
struct xfs_ail *ailp,
763-
struct xfs_log_vec *log_vector,
763+
struct list_head *lv_chain,
764764
xfs_lsn_t commit_lsn,
765765
bool aborted)
766766
{
@@ -775,7 +775,7 @@ xfs_trans_committed_bulk(
775775
spin_unlock(&ailp->ail_lock);
776776

777777
/* unpin all the log items */
778-
for (lv = log_vector; lv; lv = lv->lv_next ) {
778+
list_for_each_entry(lv, lv_chain, lv_list) {
779779
struct xfs_log_item *lip = lv->lv_item;
780780
xfs_lsn_t item_lsn;
781781

fs/xfs/xfs_trans_priv.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *);
1919
void xfs_trans_del_item(struct xfs_log_item *);
2020
void xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp);
2121

22-
void xfs_trans_committed_bulk(struct xfs_ail *ailp, struct xfs_log_vec *lv,
22+
void xfs_trans_committed_bulk(struct xfs_ail *ailp,
23+
struct list_head *lv_chain,
2324
xfs_lsn_t commit_lsn, bool aborted);
2425
/*
2526
* AIL traversal cursor.

0 commit comments

Comments
 (0)