@@ -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
686686static void
687687xlog_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(
962962static int
963963xlog_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
0 commit comments