@@ -1075,6 +1075,32 @@ static int ext4_fc_perform_commit(journal_t *journal)
10751075 return ret ;
10761076}
10771077
1078+ static void ext4_fc_update_stats (struct super_block * sb , int status ,
1079+ u64 commit_time , int nblks )
1080+ {
1081+ struct ext4_fc_stats * stats = & EXT4_SB (sb )-> s_fc_stats ;
1082+
1083+ jbd_debug (1 , "Fast commit ended with status = %d" , status );
1084+ if (status == EXT4_FC_STATUS_OK ) {
1085+ stats -> fc_num_commits ++ ;
1086+ stats -> fc_numblks += nblks ;
1087+ if (likely (stats -> s_fc_avg_commit_time ))
1088+ stats -> s_fc_avg_commit_time =
1089+ (commit_time +
1090+ stats -> s_fc_avg_commit_time * 3 ) / 4 ;
1091+ else
1092+ stats -> s_fc_avg_commit_time = commit_time ;
1093+ } else if (status == EXT4_FC_STATUS_FAILED ||
1094+ status == EXT4_FC_STATUS_INELIGIBLE ) {
1095+ if (status == EXT4_FC_STATUS_FAILED )
1096+ stats -> fc_failed_commits ++ ;
1097+ stats -> fc_ineligible_commits ++ ;
1098+ } else {
1099+ stats -> fc_skipped_commits ++ ;
1100+ }
1101+ trace_ext4_fc_commit_stop (sb , nblks , status );
1102+ }
1103+
10781104/*
10791105 * The main commit entry point. Performs a fast commit for transaction
10801106 * commit_tid if needed. If it's not possible to perform a fast commit
@@ -1087,7 +1113,7 @@ int ext4_fc_commit(journal_t *journal, tid_t commit_tid)
10871113 struct ext4_sb_info * sbi = EXT4_SB (sb );
10881114 int nblks = 0 , ret , bsize = journal -> j_blocksize ;
10891115 int subtid = atomic_read (& sbi -> s_fc_subtid );
1090- int reason = EXT4_FC_REASON_OK , fc_bufs_before = 0 ;
1116+ int status = EXT4_FC_STATUS_OK , fc_bufs_before = 0 ;
10911117 ktime_t start_time , commit_time ;
10921118
10931119 trace_ext4_fc_commit_start (sb );
@@ -1104,69 +1130,52 @@ int ext4_fc_commit(journal_t *journal, tid_t commit_tid)
11041130 if (atomic_read (& sbi -> s_fc_subtid ) <= subtid &&
11051131 commit_tid > journal -> j_commit_sequence )
11061132 goto restart_fc ;
1107- reason = EXT4_FC_REASON_ALREADY_COMMITTED ;
1108- goto out ;
1133+ ext4_fc_update_stats ( sb , EXT4_FC_STATUS_SKIPPED , 0 , 0 ) ;
1134+ return 0 ;
11091135 } else if (ret ) {
1110- sbi -> s_fc_stats .fc_ineligible_reason_count [EXT4_FC_COMMIT_FAILED ]++ ;
1111- reason = EXT4_FC_REASON_FC_START_FAILED ;
1112- goto out ;
1136+ /*
1137+ * Commit couldn't start. Just update stats and perform a
1138+ * full commit.
1139+ */
1140+ ext4_fc_update_stats (sb , EXT4_FC_STATUS_FAILED , 0 , 0 );
1141+ return jbd2_complete_transaction (journal , commit_tid );
11131142 }
1143+
11141144 /*
11151145 * After establishing journal barrier via jbd2_fc_begin_commit(), check
11161146 * if we are fast commit ineligible.
11171147 */
11181148 if (ext4_test_mount_flag (sb , EXT4_MF_FC_INELIGIBLE )) {
1119- reason = EXT4_FC_REASON_INELIGIBLE ;
1120- goto out ;
1149+ status = EXT4_FC_STATUS_INELIGIBLE ;
1150+ goto fallback ;
11211151 }
11221152
11231153 fc_bufs_before = (sbi -> s_fc_bytes + bsize - 1 ) / bsize ;
11241154 ret = ext4_fc_perform_commit (journal );
11251155 if (ret < 0 ) {
1126- sbi -> s_fc_stats .fc_ineligible_reason_count [EXT4_FC_COMMIT_FAILED ]++ ;
1127- reason = EXT4_FC_REASON_FC_FAILED ;
1128- goto out ;
1156+ status = EXT4_FC_STATUS_FAILED ;
1157+ goto fallback ;
11291158 }
11301159 nblks = (sbi -> s_fc_bytes + bsize - 1 ) / bsize - fc_bufs_before ;
11311160 ret = jbd2_fc_wait_bufs (journal , nblks );
11321161 if (ret < 0 ) {
1133- sbi -> s_fc_stats .fc_ineligible_reason_count [EXT4_FC_COMMIT_FAILED ]++ ;
1134- reason = EXT4_FC_REASON_FC_FAILED ;
1135- goto out ;
1162+ status = EXT4_FC_STATUS_FAILED ;
1163+ goto fallback ;
11361164 }
11371165 atomic_inc (& sbi -> s_fc_subtid );
1138- jbd2_fc_end_commit (journal );
1139- out :
1140- spin_lock (& sbi -> s_fc_lock );
1141- if (reason != EXT4_FC_REASON_OK &&
1142- reason != EXT4_FC_REASON_ALREADY_COMMITTED ) {
1143- sbi -> s_fc_stats .fc_ineligible_commits ++ ;
1144- } else {
1145- sbi -> s_fc_stats .fc_num_commits ++ ;
1146- sbi -> s_fc_stats .fc_numblks += nblks ;
1147- }
1148- spin_unlock (& sbi -> s_fc_lock );
1149- nblks = (reason == EXT4_FC_REASON_OK ) ? nblks : 0 ;
1150- trace_ext4_fc_commit_stop (sb , nblks , reason );
1151- commit_time = ktime_to_ns (ktime_sub (ktime_get (), start_time ));
1166+ ret = jbd2_fc_end_commit (journal );
11521167 /*
1153- * weight the commit time higher than the average time so we don't
1154- * react too strongly to vast changes in the commit time
1168+ * weight the commit time higher than the average time so we
1169+ * don't react too strongly to vast changes in the commit time
11551170 */
1156- if (likely (sbi -> s_fc_avg_commit_time ))
1157- sbi -> s_fc_avg_commit_time = (commit_time +
1158- sbi -> s_fc_avg_commit_time * 3 ) / 4 ;
1159- else
1160- sbi -> s_fc_avg_commit_time = commit_time ;
1161- jbd_debug (1 ,
1162- "Fast commit ended with blks = %d, reason = %d, subtid - %d" ,
1163- nblks , reason , subtid );
1164- if (reason == EXT4_FC_REASON_FC_FAILED )
1165- return jbd2_fc_end_commit_fallback (journal );
1166- if (reason == EXT4_FC_REASON_FC_START_FAILED ||
1167- reason == EXT4_FC_REASON_INELIGIBLE )
1168- return jbd2_complete_transaction (journal , commit_tid );
1169- return 0 ;
1171+ commit_time = ktime_to_ns (ktime_sub (ktime_get (), start_time ));
1172+ ext4_fc_update_stats (sb , status , commit_time , nblks );
1173+ return ret ;
1174+
1175+ fallback :
1176+ ret = jbd2_fc_end_commit_fallback (journal );
1177+ ext4_fc_update_stats (sb , status , 0 , 0 );
1178+ return ret ;
11701179}
11711180
11721181/*
@@ -2124,7 +2133,7 @@ int ext4_fc_info_show(struct seq_file *seq, void *v)
21242133 "fc stats:\n%ld commits\n%ld ineligible\n%ld numblks\n%lluus avg_commit_time\n" ,
21252134 stats -> fc_num_commits , stats -> fc_ineligible_commits ,
21262135 stats -> fc_numblks ,
2127- div_u64 (sbi -> s_fc_avg_commit_time , 1000 ));
2136+ div_u64 (stats -> s_fc_avg_commit_time , 1000 ));
21282137 seq_puts (seq , "Ineligible reasons:\n" );
21292138 for (i = 0 ; i < EXT4_FC_REASON_MAX ; i ++ )
21302139 seq_printf (seq , "\"%s\":\t%d\n" , fc_ineligible_reasons [i ],
0 commit comments