summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/xfs/xfs_log.h1
-rw-r--r--fs/xfs/xfs_log_cil.c16
2 files changed, 12 insertions, 5 deletions
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index e7bf3c780cb4..2728886c2963 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -10,6 +10,7 @@ struct xfs_cil_ctx;
struct xfs_log_vec {
struct list_head lv_list; /* CIL lv chain ptrs */
+ uint32_t lv_order_id; /* chain ordering info */
int lv_niovecs; /* number of iovecs in lv */
struct xfs_log_iovec *lv_iovecp; /* iovec array */
struct xfs_log_item *lv_item; /* owner */
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index 0e69e855d710..8bb251d2b4d3 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -1095,10 +1095,10 @@ xlog_cil_order_cmp(
const struct list_head *a,
const struct list_head *b)
{
- struct xfs_log_item *l1 = container_of(a, struct xfs_log_item, li_cil);
- struct xfs_log_item *l2 = container_of(b, struct xfs_log_item, li_cil);
+ struct xfs_log_vec *l1 = container_of(a, struct xfs_log_vec, lv_list);
+ struct xfs_log_vec *l2 = container_of(b, struct xfs_log_vec, lv_list);
- return l1->li_order_id > l2->li_order_id;
+ return l1->lv_order_id > l2->lv_order_id;
}
/*
@@ -1117,8 +1117,6 @@ xlog_cil_build_lv_chain(
uint32_t *num_iovecs,
uint32_t *num_bytes)
{
- list_sort(NULL, &ctx->log_items, xlog_cil_order_cmp);
-
while (!list_empty(&ctx->log_items)) {
struct xfs_log_item *item;
struct xfs_log_vec *lv;
@@ -1133,6 +1131,7 @@ xlog_cil_build_lv_chain(
}
lv = item->li_lv;
+ lv->lv_order_id = item->li_order_id;
/* we don't write ordered log vectors */
if (lv->lv_buf_len != XFS_LOG_VEC_ORDERED)
@@ -1293,6 +1292,13 @@ xlog_cil_push_work(
up_write(&cil->xc_ctx_lock);
/*
+ * Sort the log vector chain before we add the transaction headers.
+ * This ensures we always have the transaction headers at the start
+ * of the chain.
+ */
+ list_sort(NULL, &ctx->lv_chain, xlog_cil_order_cmp);
+
+ /*
* Build a checkpoint transaction header and write it to the log to
* begin the transaction. We need to account for the space used by the
* transaction header here as it is not accounted for in xlog_write().