@@ -47,6 +47,38 @@ xlog_cil_ticket_alloc(
47
47
return tic ;
48
48
}
49
49
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
+
50
82
/*
51
83
* Unavoidable forward declaration - xlog_cil_push_work() calls
52
84
* xlog_cil_ctx_alloc() itself.
@@ -934,6 +966,40 @@ xlog_cil_build_trans_hdr(
934
966
tic -> t_curr_res -= lvhdr -> lv_bytes ;
935
967
}
936
968
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
+
937
1003
/*
938
1004
* Push the Committed Item List to the log.
939
1005
*
@@ -956,7 +1022,6 @@ xlog_cil_push_work(
956
1022
container_of (work , struct xfs_cil_ctx , push_work );
957
1023
struct xfs_cil * cil = ctx -> cil ;
958
1024
struct xlog * log = cil -> xc_log ;
959
- struct xfs_log_vec * lv ;
960
1025
struct xfs_cil_ctx * new_ctx ;
961
1026
int num_iovecs = 0 ;
962
1027
int num_bytes = 0 ;
@@ -1033,31 +1098,7 @@ xlog_cil_push_work(
1033
1098
list_add (& ctx -> committing , & cil -> xc_committing );
1034
1099
spin_unlock (& cil -> xc_push_lock );
1035
1100
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 );
1061
1102
1062
1103
/*
1063
1104
* Switch the contexts so we can drop the context lock and move out
@@ -1508,32 +1549,6 @@ xlog_cil_force_seq(
1508
1549
return 0 ;
1509
1550
}
1510
1551
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
-
1537
1552
/*
1538
1553
* Perform initial CIL structure initialisation.
1539
1554
*/
0 commit comments