@@ -159,7 +159,9 @@ static void commit_timeout(struct timer_list *t)
159159 *
160160 * 1) COMMIT: Every so often we need to commit the current state of the
161161 * filesystem to disk. The journal thread is responsible for writing
162- * all of the metadata buffers to disk.
162+ * all of the metadata buffers to disk. If a fast commit is ongoing
163+ * journal thread waits until it's done and then continues from
164+ * there on.
163165 *
164166 * 2) CHECKPOINT: We cannot reuse a used section of the log file until all
165167 * of the data in that part of the log has been rewritten elsewhere on
@@ -716,6 +718,75 @@ int jbd2_log_wait_commit(journal_t *journal, tid_t tid)
716718 return err ;
717719}
718720
721+ /*
722+ * Start a fast commit. If there's an ongoing fast or full commit wait for
723+ * it to complete. Returns 0 if a new fast commit was started. Returns -EALREADY
724+ * if a fast commit is not needed, either because there's an already a commit
725+ * going on or this tid has already been committed. Returns -EINVAL if no jbd2
726+ * commit has yet been performed.
727+ */
728+ int jbd2_fc_begin_commit (journal_t * journal , tid_t tid )
729+ {
730+ /*
731+ * Fast commits only allowed if at least one full commit has
732+ * been processed.
733+ */
734+ if (!journal -> j_stats .ts_tid )
735+ return - EINVAL ;
736+
737+ if (tid <= journal -> j_commit_sequence )
738+ return - EALREADY ;
739+
740+ write_lock (& journal -> j_state_lock );
741+ if (journal -> j_flags & JBD2_FULL_COMMIT_ONGOING ||
742+ (journal -> j_flags & JBD2_FAST_COMMIT_ONGOING )) {
743+ DEFINE_WAIT (wait );
744+
745+ prepare_to_wait (& journal -> j_fc_wait , & wait ,
746+ TASK_UNINTERRUPTIBLE );
747+ write_unlock (& journal -> j_state_lock );
748+ schedule ();
749+ finish_wait (& journal -> j_fc_wait , & wait );
750+ return - EALREADY ;
751+ }
752+ journal -> j_flags |= JBD2_FAST_COMMIT_ONGOING ;
753+ write_unlock (& journal -> j_state_lock );
754+
755+ return 0 ;
756+ }
757+ EXPORT_SYMBOL (jbd2_fc_begin_commit );
758+
759+ /*
760+ * Stop a fast commit. If fallback is set, this function starts commit of
761+ * TID tid before any other fast commit can start.
762+ */
763+ static int __jbd2_fc_end_commit (journal_t * journal , tid_t tid , bool fallback )
764+ {
765+ if (journal -> j_fc_cleanup_callback )
766+ journal -> j_fc_cleanup_callback (journal , 0 );
767+ write_lock (& journal -> j_state_lock );
768+ journal -> j_flags &= ~JBD2_FAST_COMMIT_ONGOING ;
769+ if (fallback )
770+ journal -> j_flags |= JBD2_FULL_COMMIT_ONGOING ;
771+ write_unlock (& journal -> j_state_lock );
772+ wake_up (& journal -> j_fc_wait );
773+ if (fallback )
774+ return jbd2_complete_transaction (journal , tid );
775+ return 0 ;
776+ }
777+
778+ int jbd2_fc_end_commit (journal_t * journal )
779+ {
780+ return __jbd2_fc_end_commit (journal , 0 , 0 );
781+ }
782+ EXPORT_SYMBOL (jbd2_fc_end_commit );
783+
784+ int jbd2_fc_end_commit_fallback (journal_t * journal , tid_t tid )
785+ {
786+ return __jbd2_fc_end_commit (journal , tid , 1 );
787+ }
788+ EXPORT_SYMBOL (jbd2_fc_end_commit_fallback );
789+
719790/* Return 1 when transaction with given tid has already committed. */
720791int jbd2_transaction_committed (journal_t * journal , tid_t tid )
721792{
@@ -784,6 +855,110 @@ int jbd2_journal_next_log_block(journal_t *journal, unsigned long long *retp)
784855 return jbd2_journal_bmap (journal , blocknr , retp );
785856}
786857
858+ /* Map one fast commit buffer for use by the file system */
859+ int jbd2_fc_get_buf (journal_t * journal , struct buffer_head * * bh_out )
860+ {
861+ unsigned long long pblock ;
862+ unsigned long blocknr ;
863+ int ret = 0 ;
864+ struct buffer_head * bh ;
865+ int fc_off ;
866+
867+ * bh_out = NULL ;
868+ write_lock (& journal -> j_state_lock );
869+
870+ if (journal -> j_fc_off + journal -> j_fc_first < journal -> j_fc_last ) {
871+ fc_off = journal -> j_fc_off ;
872+ blocknr = journal -> j_fc_first + fc_off ;
873+ journal -> j_fc_off ++ ;
874+ } else {
875+ ret = - EINVAL ;
876+ }
877+ write_unlock (& journal -> j_state_lock );
878+
879+ if (ret )
880+ return ret ;
881+
882+ ret = jbd2_journal_bmap (journal , blocknr , & pblock );
883+ if (ret )
884+ return ret ;
885+
886+ bh = __getblk (journal -> j_dev , pblock , journal -> j_blocksize );
887+ if (!bh )
888+ return - ENOMEM ;
889+
890+ lock_buffer (bh );
891+
892+ clear_buffer_uptodate (bh );
893+ set_buffer_dirty (bh );
894+ unlock_buffer (bh );
895+ journal -> j_fc_wbuf [fc_off ] = bh ;
896+
897+ * bh_out = bh ;
898+
899+ return 0 ;
900+ }
901+ EXPORT_SYMBOL (jbd2_fc_get_buf );
902+
903+ /*
904+ * Wait on fast commit buffers that were allocated by jbd2_fc_get_buf
905+ * for completion.
906+ */
907+ int jbd2_fc_wait_bufs (journal_t * journal , int num_blks )
908+ {
909+ struct buffer_head * bh ;
910+ int i , j_fc_off ;
911+
912+ read_lock (& journal -> j_state_lock );
913+ j_fc_off = journal -> j_fc_off ;
914+ read_unlock (& journal -> j_state_lock );
915+
916+ /*
917+ * Wait in reverse order to minimize chances of us being woken up before
918+ * all IOs have completed
919+ */
920+ for (i = j_fc_off - 1 ; i >= j_fc_off - num_blks ; i -- ) {
921+ bh = journal -> j_fc_wbuf [i ];
922+ wait_on_buffer (bh );
923+ put_bh (bh );
924+ journal -> j_fc_wbuf [i ] = NULL ;
925+ if (unlikely (!buffer_uptodate (bh )))
926+ return - EIO ;
927+ }
928+
929+ return 0 ;
930+ }
931+ EXPORT_SYMBOL (jbd2_fc_wait_bufs );
932+
933+ /*
934+ * Wait on fast commit buffers that were allocated by jbd2_fc_get_buf
935+ * for completion.
936+ */
937+ int jbd2_fc_release_bufs (journal_t * journal )
938+ {
939+ struct buffer_head * bh ;
940+ int i , j_fc_off ;
941+
942+ read_lock (& journal -> j_state_lock );
943+ j_fc_off = journal -> j_fc_off ;
944+ read_unlock (& journal -> j_state_lock );
945+
946+ /*
947+ * Wait in reverse order to minimize chances of us being woken up before
948+ * all IOs have completed
949+ */
950+ for (i = j_fc_off - 1 ; i >= 0 ; i -- ) {
951+ bh = journal -> j_fc_wbuf [i ];
952+ if (!bh )
953+ break ;
954+ put_bh (bh );
955+ journal -> j_fc_wbuf [i ] = NULL ;
956+ }
957+
958+ return 0 ;
959+ }
960+ EXPORT_SYMBOL (jbd2_fc_release_bufs );
961+
787962/*
788963 * Conversion of logical to physical block numbers for the journal
789964 *
@@ -1142,6 +1317,7 @@ static journal_t *journal_init_common(struct block_device *bdev,
11421317 init_waitqueue_head (& journal -> j_wait_commit );
11431318 init_waitqueue_head (& journal -> j_wait_updates );
11441319 init_waitqueue_head (& journal -> j_wait_reserved );
1320+ init_waitqueue_head (& journal -> j_fc_wait );
11451321 mutex_init (& journal -> j_abort_mutex );
11461322 mutex_init (& journal -> j_barrier );
11471323 mutex_init (& journal -> j_checkpoint_mutex );
@@ -1495,6 +1671,7 @@ int jbd2_journal_update_sb_log_tail(journal_t *journal, tid_t tail_tid,
14951671static void jbd2_mark_journal_empty (journal_t * journal , int write_op )
14961672{
14971673 journal_superblock_t * sb = journal -> j_superblock ;
1674+ bool had_fast_commit = false;
14981675
14991676 BUG_ON (!mutex_is_locked (& journal -> j_checkpoint_mutex ));
15001677 lock_buffer (journal -> j_sb_buffer );
@@ -1508,9 +1685,20 @@ static void jbd2_mark_journal_empty(journal_t *journal, int write_op)
15081685
15091686 sb -> s_sequence = cpu_to_be32 (journal -> j_tail_sequence );
15101687 sb -> s_start = cpu_to_be32 (0 );
1688+ if (jbd2_has_feature_fast_commit (journal )) {
1689+ /*
1690+ * When journal is clean, no need to commit fast commit flag and
1691+ * make file system incompatible with older kernels.
1692+ */
1693+ jbd2_clear_feature_fast_commit (journal );
1694+ had_fast_commit = true;
1695+ }
15111696
15121697 jbd2_write_superblock (journal , write_op );
15131698
1699+ if (had_fast_commit )
1700+ jbd2_set_feature_fast_commit (journal );
1701+
15141702 /* Log is no longer empty */
15151703 write_lock (& journal -> j_state_lock );
15161704 journal -> j_flags |= JBD2_FLUSHED ;
0 commit comments