@@ -47,6 +47,38 @@ xlog_cil_ticket_alloc(
4747 return tic ;
4848}
4949
50+ /*
51+ * Check if the current log item was first committed in this sequence.
52+ * We can't rely on just the log item being in the CIL, we have to check
53+ * the recorded commit sequence number.
54+ *
55+ * Note: for this to be used in a non-racy manner, it has to be called with
56+ * CIL flushing locked out. As a result, it should only be used during the
57+ * transaction commit process when deciding what to format into the item.
58+ */
59+ static bool
60+ xlog_item_in_current_chkpt (
61+ struct xfs_cil * cil ,
62+ struct xfs_log_item * lip )
63+ {
64+ if (list_empty (& lip -> li_cil ))
65+ return false;
66+
67+ /*
68+ * li_seq is written on the first commit of a log item to record the
69+ * first checkpoint it is written to. Hence if it is different to the
70+ * current sequence, we're in a new checkpoint.
71+ */
72+ return lip -> li_seq == READ_ONCE (cil -> xc_current_sequence );
73+ }
74+
75+ bool
76+ xfs_log_item_in_current_chkpt (
77+ struct xfs_log_item * lip )
78+ {
79+ return xlog_item_in_current_chkpt (lip -> li_log -> l_cilp , lip );
80+ }
81+
5082/*
5183 * Unavoidable forward declaration - xlog_cil_push_work() calls
5284 * xlog_cil_ctx_alloc() itself.
@@ -934,6 +966,40 @@ xlog_cil_build_trans_hdr(
934966 tic -> t_curr_res -= lvhdr -> lv_bytes ;
935967}
936968
969+ /*
970+ * Pull all the log vectors off the items in the CIL, and remove the items from
971+ * the CIL. We don't need the CIL lock here because it's only needed on the
972+ * transaction commit side which is currently locked out by the flush lock.
973+ */
974+ static void
975+ xlog_cil_build_lv_chain (
976+ struct xfs_cil * cil ,
977+ struct xfs_cil_ctx * ctx ,
978+ uint32_t * num_iovecs ,
979+ uint32_t * num_bytes )
980+ {
981+ struct xfs_log_vec * lv = NULL ;
982+
983+ while (!list_empty (& cil -> xc_cil )) {
984+ struct xfs_log_item * item ;
985+
986+ item = list_first_entry (& cil -> xc_cil ,
987+ struct xfs_log_item , li_cil );
988+ list_del_init (& item -> li_cil );
989+ if (!ctx -> lv_chain )
990+ ctx -> lv_chain = item -> li_lv ;
991+ else
992+ lv -> lv_next = item -> li_lv ;
993+ lv = item -> li_lv ;
994+ item -> li_lv = NULL ;
995+ * num_iovecs += lv -> lv_niovecs ;
996+
997+ /* we don't write ordered log vectors */
998+ if (lv -> lv_buf_len != XFS_LOG_VEC_ORDERED )
999+ * num_bytes += lv -> lv_bytes ;
1000+ }
1001+ }
1002+
9371003/*
9381004 * Push the Committed Item List to the log.
9391005 *
@@ -956,7 +1022,6 @@ xlog_cil_push_work(
9561022 container_of (work , struct xfs_cil_ctx , push_work );
9571023 struct xfs_cil * cil = ctx -> cil ;
9581024 struct xlog * log = cil -> xc_log ;
959- struct xfs_log_vec * lv ;
9601025 struct xfs_cil_ctx * new_ctx ;
9611026 int num_iovecs = 0 ;
9621027 int num_bytes = 0 ;
@@ -1033,31 +1098,7 @@ xlog_cil_push_work(
10331098 list_add (& ctx -> committing , & cil -> xc_committing );
10341099 spin_unlock (& cil -> xc_push_lock );
10351100
1036- /*
1037- * Pull all the log vectors off the items in the CIL, and remove the
1038- * items from the CIL. We don't need the CIL lock here because it's only
1039- * needed on the transaction commit side which is currently locked out
1040- * by the flush lock.
1041- */
1042- lv = NULL ;
1043- while (!list_empty (& cil -> xc_cil )) {
1044- struct xfs_log_item * item ;
1045-
1046- item = list_first_entry (& cil -> xc_cil ,
1047- struct xfs_log_item , li_cil );
1048- list_del_init (& item -> li_cil );
1049- if (!ctx -> lv_chain )
1050- ctx -> lv_chain = item -> li_lv ;
1051- else
1052- lv -> lv_next = item -> li_lv ;
1053- lv = item -> li_lv ;
1054- item -> li_lv = NULL ;
1055- num_iovecs += lv -> lv_niovecs ;
1056-
1057- /* we don't write ordered log vectors */
1058- if (lv -> lv_buf_len != XFS_LOG_VEC_ORDERED )
1059- num_bytes += lv -> lv_bytes ;
1060- }
1101+ xlog_cil_build_lv_chain (cil , ctx , & num_iovecs , & num_bytes );
10611102
10621103 /*
10631104 * Switch the contexts so we can drop the context lock and move out
@@ -1508,32 +1549,6 @@ xlog_cil_force_seq(
15081549 return 0 ;
15091550}
15101551
1511- /*
1512- * Check if the current log item was first committed in this sequence.
1513- * We can't rely on just the log item being in the CIL, we have to check
1514- * the recorded commit sequence number.
1515- *
1516- * Note: for this to be used in a non-racy manner, it has to be called with
1517- * CIL flushing locked out. As a result, it should only be used during the
1518- * transaction commit process when deciding what to format into the item.
1519- */
1520- bool
1521- xfs_log_item_in_current_chkpt (
1522- struct xfs_log_item * lip )
1523- {
1524- struct xfs_cil * cil = lip -> li_log -> l_cilp ;
1525-
1526- if (list_empty (& lip -> li_cil ))
1527- return false;
1528-
1529- /*
1530- * li_seq is written on the first commit of a log item to record the
1531- * first checkpoint it is written to. Hence if it is different to the
1532- * current sequence, we're in a new checkpoint.
1533- */
1534- return lip -> li_seq == READ_ONCE (cil -> xc_current_sequence );
1535- }
1536-
15371552/*
15381553 * Perform initial CIL structure initialisation.
15391554 */
0 commit comments