@@ -1181,6 +1181,14 @@ static journal_t *journal_init_common(struct block_device *bdev,
11811181 if (!journal -> j_wbuf )
11821182 goto err_cleanup ;
11831183
1184+ if (journal -> j_fc_wbufsize > 0 ) {
1185+ journal -> j_fc_wbuf = kmalloc_array (journal -> j_fc_wbufsize ,
1186+ sizeof (struct buffer_head * ),
1187+ GFP_KERNEL );
1188+ if (!journal -> j_fc_wbuf )
1189+ goto err_cleanup ;
1190+ }
1191+
11841192 bh = getblk_unmovable (journal -> j_dev , start , journal -> j_blocksize );
11851193 if (!bh ) {
11861194 pr_err ("%s: Cannot get buffer for journal superblock\n" ,
@@ -1194,11 +1202,23 @@ static journal_t *journal_init_common(struct block_device *bdev,
11941202
11951203err_cleanup :
11961204 kfree (journal -> j_wbuf );
1205+ kfree (journal -> j_fc_wbuf );
11971206 jbd2_journal_destroy_revoke (journal );
11981207 kfree (journal );
11991208 return NULL ;
12001209}
12011210
1211+ int jbd2_fc_init (journal_t * journal , int num_fc_blks )
1212+ {
1213+ journal -> j_fc_wbufsize = num_fc_blks ;
1214+ journal -> j_fc_wbuf = kmalloc_array (journal -> j_fc_wbufsize ,
1215+ sizeof (struct buffer_head * ), GFP_KERNEL );
1216+ if (!journal -> j_fc_wbuf )
1217+ return - ENOMEM ;
1218+ return 0 ;
1219+ }
1220+ EXPORT_SYMBOL (jbd2_fc_init );
1221+
12021222/* jbd2_journal_init_dev and jbd2_journal_init_inode:
12031223 *
12041224 * Create a journal structure assigned some fixed set of disk blocks to
@@ -1316,11 +1336,20 @@ static int journal_reset(journal_t *journal)
13161336 }
13171337
13181338 journal -> j_first = first ;
1319- journal -> j_last = last ;
13201339
1321- journal -> j_head = first ;
1322- journal -> j_tail = first ;
1323- journal -> j_free = last - first ;
1340+ if (jbd2_has_feature_fast_commit (journal ) &&
1341+ journal -> j_fc_wbufsize > 0 ) {
1342+ journal -> j_fc_last = last ;
1343+ journal -> j_last = last - journal -> j_fc_wbufsize ;
1344+ journal -> j_fc_first = journal -> j_last + 1 ;
1345+ journal -> j_fc_off = 0 ;
1346+ } else {
1347+ journal -> j_last = last ;
1348+ }
1349+
1350+ journal -> j_head = journal -> j_first ;
1351+ journal -> j_tail = journal -> j_first ;
1352+ journal -> j_free = journal -> j_last - journal -> j_first ;
13241353
13251354 journal -> j_tail_sequence = journal -> j_transaction_sequence ;
13261355 journal -> j_commit_sequence = journal -> j_transaction_sequence - 1 ;
@@ -1665,9 +1694,18 @@ static int load_superblock(journal_t *journal)
16651694 journal -> j_tail_sequence = be32_to_cpu (sb -> s_sequence );
16661695 journal -> j_tail = be32_to_cpu (sb -> s_start );
16671696 journal -> j_first = be32_to_cpu (sb -> s_first );
1668- journal -> j_last = be32_to_cpu (sb -> s_maxlen );
16691697 journal -> j_errno = be32_to_cpu (sb -> s_errno );
16701698
1699+ if (jbd2_has_feature_fast_commit (journal ) &&
1700+ journal -> j_fc_wbufsize > 0 ) {
1701+ journal -> j_fc_last = be32_to_cpu (sb -> s_maxlen );
1702+ journal -> j_last = journal -> j_fc_last - journal -> j_fc_wbufsize ;
1703+ journal -> j_fc_first = journal -> j_last + 1 ;
1704+ journal -> j_fc_off = 0 ;
1705+ } else {
1706+ journal -> j_last = be32_to_cpu (sb -> s_maxlen );
1707+ }
1708+
16711709 return 0 ;
16721710}
16731711
@@ -1728,6 +1766,9 @@ int jbd2_journal_load(journal_t *journal)
17281766 */
17291767 journal -> j_flags &= ~JBD2_ABORT ;
17301768
1769+ if (journal -> j_fc_wbufsize > 0 )
1770+ jbd2_journal_set_features (journal , 0 , 0 ,
1771+ JBD2_FEATURE_INCOMPAT_FAST_COMMIT );
17311772 /* OK, we've finished with the dynamic journal bits:
17321773 * reinitialise the dynamic contents of the superblock in memory
17331774 * and reset them on disk. */
@@ -1811,6 +1852,8 @@ int jbd2_journal_destroy(journal_t *journal)
18111852 jbd2_journal_destroy_revoke (journal );
18121853 if (journal -> j_chksum_driver )
18131854 crypto_free_shash (journal -> j_chksum_driver );
1855+ if (journal -> j_fc_wbufsize > 0 )
1856+ kfree (journal -> j_fc_wbuf );
18141857 kfree (journal -> j_wbuf );
18151858 kfree (journal );
18161859
0 commit comments