LCOV - code coverage report
Current view: top level - fs/jbd2 - checkpoint.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 0 299 0.0 %
Date: 2023-07-31 20:08:27 Functions: 0 13 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0+
       2             : /*
       3             :  * linux/fs/jbd2/checkpoint.c
       4             :  *
       5             :  * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
       6             :  *
       7             :  * Copyright 1999 Red Hat Software --- All Rights Reserved
       8             :  *
       9             :  * Checkpoint routines for the generic filesystem journaling code.
      10             :  * Part of the ext2fs journaling system.
      11             :  *
      12             :  * Checkpointing is the process of ensuring that a section of the log is
      13             :  * committed fully to disk, so that that portion of the log can be
      14             :  * reused.
      15             :  */
      16             : 
      17             : #include <linux/time.h>
      18             : #include <linux/fs.h>
      19             : #include <linux/jbd2.h>
      20             : #include <linux/errno.h>
      21             : #include <linux/slab.h>
      22             : #include <linux/blkdev.h>
      23             : #include <trace/events/jbd2.h>
      24             : 
      25             : /*
      26             :  * Unlink a buffer from a transaction checkpoint list.
      27             :  *
      28             :  * Called with j_list_lock held.
      29             :  */
      30           0 : static inline void __buffer_unlink(struct journal_head *jh)
      31             : {
      32           0 :         transaction_t *transaction = jh->b_cp_transaction;
      33             : 
      34           0 :         jh->b_cpnext->b_cpprev = jh->b_cpprev;
      35           0 :         jh->b_cpprev->b_cpnext = jh->b_cpnext;
      36           0 :         if (transaction->t_checkpoint_list == jh) {
      37           0 :                 transaction->t_checkpoint_list = jh->b_cpnext;
      38           0 :                 if (transaction->t_checkpoint_list == jh)
      39           0 :                         transaction->t_checkpoint_list = NULL;
      40             :         }
      41           0 : }
      42             : 
      43             : /*
      44             :  * Check a checkpoint buffer could be release or not.
      45             :  *
      46             :  * Requires j_list_lock
      47             :  */
      48             : static inline bool __cp_buffer_busy(struct journal_head *jh)
      49             : {
      50             :         struct buffer_head *bh = jh2bh(jh);
      51             : 
      52             :         return (jh->b_transaction || buffer_locked(bh) || buffer_dirty(bh));
      53             : }
      54             : 
      55             : /*
      56             :  * __jbd2_log_wait_for_space: wait until there is space in the journal.
      57             :  *
      58             :  * Called under j-state_lock *only*.  It will be unlocked if we have to wait
      59             :  * for a checkpoint to free up some space in the log.
      60             :  */
      61           0 : void __jbd2_log_wait_for_space(journal_t *journal)
      62             : __acquires(&journal->j_state_lock)
      63             : __releases(&journal->j_state_lock)
      64             : {
      65           0 :         int nblocks, space_left;
      66             :         /* assert_spin_locked(&journal->j_state_lock); */
      67             : 
      68           0 :         nblocks = journal->j_max_transaction_buffers;
      69           0 :         while (jbd2_log_space_left(journal) < nblocks) {
      70           0 :                 write_unlock(&journal->j_state_lock);
      71           0 :                 mutex_lock_io(&journal->j_checkpoint_mutex);
      72             : 
      73             :                 /*
      74             :                  * Test again, another process may have checkpointed while we
      75             :                  * were waiting for the checkpoint lock. If there are no
      76             :                  * transactions ready to be checkpointed, try to recover
      77             :                  * journal space by calling cleanup_journal_tail(), and if
      78             :                  * that doesn't work, by waiting for the currently committing
      79             :                  * transaction to complete.  If there is absolutely no way
      80             :                  * to make progress, this is either a BUG or corrupted
      81             :                  * filesystem, so abort the journal and leave a stack
      82             :                  * trace for forensic evidence.
      83             :                  */
      84           0 :                 write_lock(&journal->j_state_lock);
      85           0 :                 if (journal->j_flags & JBD2_ABORT) {
      86           0 :                         mutex_unlock(&journal->j_checkpoint_mutex);
      87           0 :                         return;
      88             :                 }
      89           0 :                 spin_lock(&journal->j_list_lock);
      90           0 :                 space_left = jbd2_log_space_left(journal);
      91           0 :                 if (space_left < nblocks) {
      92           0 :                         int chkpt = journal->j_checkpoint_transactions != NULL;
      93           0 :                         tid_t tid = 0;
      94             : 
      95           0 :                         if (journal->j_committing_transaction)
      96           0 :                                 tid = journal->j_committing_transaction->t_tid;
      97           0 :                         spin_unlock(&journal->j_list_lock);
      98           0 :                         write_unlock(&journal->j_state_lock);
      99           0 :                         if (chkpt) {
     100           0 :                                 jbd2_log_do_checkpoint(journal);
     101           0 :                         } else if (jbd2_cleanup_journal_tail(journal) == 0) {
     102             :                                 /* We were able to recover space; yay! */
     103             :                                 ;
     104           0 :                         } else if (tid) {
     105             :                                 /*
     106             :                                  * jbd2_journal_commit_transaction() may want
     107             :                                  * to take the checkpoint_mutex if JBD2_FLUSHED
     108             :                                  * is set.  So we need to temporarily drop it.
     109             :                                  */
     110           0 :                                 mutex_unlock(&journal->j_checkpoint_mutex);
     111           0 :                                 jbd2_log_wait_commit(journal, tid);
     112           0 :                                 write_lock(&journal->j_state_lock);
     113           0 :                                 continue;
     114             :                         } else {
     115           0 :                                 printk(KERN_ERR "%s: needed %d blocks and "
     116             :                                        "only had %d space available\n",
     117             :                                        __func__, nblocks, space_left);
     118           0 :                                 printk(KERN_ERR "%s: no way to get more "
     119             :                                        "journal space in %s\n", __func__,
     120             :                                        journal->j_devname);
     121           0 :                                 WARN_ON(1);
     122           0 :                                 jbd2_journal_abort(journal, -EIO);
     123             :                         }
     124           0 :                         write_lock(&journal->j_state_lock);
     125             :                 } else {
     126           0 :                         spin_unlock(&journal->j_list_lock);
     127             :                 }
     128           0 :                 mutex_unlock(&journal->j_checkpoint_mutex);
     129             :         }
     130             : }
     131             : 
     132             : static void
     133           0 : __flush_batch(journal_t *journal, int *batch_count)
     134             : {
     135           0 :         int i;
     136           0 :         struct blk_plug plug;
     137             : 
     138           0 :         blk_start_plug(&plug);
     139           0 :         for (i = 0; i < *batch_count; i++)
     140           0 :                 write_dirty_buffer(journal->j_chkpt_bhs[i], REQ_SYNC);
     141           0 :         blk_finish_plug(&plug);
     142             : 
     143           0 :         for (i = 0; i < *batch_count; i++) {
     144           0 :                 struct buffer_head *bh = journal->j_chkpt_bhs[i];
     145           0 :                 BUFFER_TRACE(bh, "brelse");
     146           0 :                 __brelse(bh);
     147           0 :                 journal->j_chkpt_bhs[i] = NULL;
     148             :         }
     149           0 :         *batch_count = 0;
     150           0 : }
     151             : 
     152             : /*
     153             :  * Perform an actual checkpoint. We take the first transaction on the
     154             :  * list of transactions to be checkpointed and send all its buffers
     155             :  * to disk. We submit larger chunks of data at once.
     156             :  *
     157             :  * The journal should be locked before calling this function.
     158             :  * Called with j_checkpoint_mutex held.
     159             :  */
     160           0 : int jbd2_log_do_checkpoint(journal_t *journal)
     161             : {
     162           0 :         struct journal_head     *jh;
     163           0 :         struct buffer_head      *bh;
     164           0 :         transaction_t           *transaction;
     165           0 :         tid_t                   this_tid;
     166           0 :         int                     result, batch_count = 0;
     167             : 
     168           0 :         jbd2_debug(1, "Start checkpoint\n");
     169             : 
     170             :         /*
     171             :          * First thing: if there are any transactions in the log which
     172             :          * don't need checkpointing, just eliminate them from the
     173             :          * journal straight away.
     174             :          */
     175           0 :         result = jbd2_cleanup_journal_tail(journal);
     176           0 :         trace_jbd2_checkpoint(journal, result);
     177           0 :         jbd2_debug(1, "cleanup_journal_tail returned %d\n", result);
     178           0 :         if (result <= 0)
     179             :                 return result;
     180             : 
     181             :         /*
     182             :          * OK, we need to start writing disk blocks.  Take one transaction
     183             :          * and write it.
     184             :          */
     185           0 :         spin_lock(&journal->j_list_lock);
     186           0 :         if (!journal->j_checkpoint_transactions)
     187           0 :                 goto out;
     188           0 :         transaction = journal->j_checkpoint_transactions;
     189           0 :         if (transaction->t_chp_stats.cs_chp_time == 0)
     190           0 :                 transaction->t_chp_stats.cs_chp_time = jiffies;
     191           0 :         this_tid = transaction->t_tid;
     192             : restart:
     193             :         /*
     194             :          * If someone cleaned up this transaction while we slept, we're
     195             :          * done (maybe it's a new transaction, but it fell at the same
     196             :          * address).
     197             :          */
     198           0 :         if (journal->j_checkpoint_transactions != transaction ||
     199           0 :             transaction->t_tid != this_tid)
     200           0 :                 goto out;
     201             : 
     202             :         /* checkpoint all of the transaction's buffers */
     203           0 :         while (transaction->t_checkpoint_list) {
     204           0 :                 jh = transaction->t_checkpoint_list;
     205           0 :                 bh = jh2bh(jh);
     206             : 
     207           0 :                 if (jh->b_transaction != NULL) {
     208           0 :                         transaction_t *t = jh->b_transaction;
     209           0 :                         tid_t tid = t->t_tid;
     210             : 
     211           0 :                         transaction->t_chp_stats.cs_forced_to_close++;
     212           0 :                         spin_unlock(&journal->j_list_lock);
     213           0 :                         if (unlikely(journal->j_flags & JBD2_UNMOUNT))
     214             :                                 /*
     215             :                                  * The journal thread is dead; so
     216             :                                  * starting and waiting for a commit
     217             :                                  * to finish will cause us to wait for
     218             :                                  * a _very_ long time.
     219             :                                  */
     220           0 :                                 printk(KERN_ERR
     221             :                 "JBD2: %s: Waiting for Godot: block %llu\n",
     222             :                 journal->j_devname, (unsigned long long) bh->b_blocknr);
     223             : 
     224           0 :                         if (batch_count)
     225           0 :                                 __flush_batch(journal, &batch_count);
     226           0 :                         jbd2_log_start_commit(journal, tid);
     227             :                         /*
     228             :                          * jbd2_journal_commit_transaction() may want
     229             :                          * to take the checkpoint_mutex if JBD2_FLUSHED
     230             :                          * is set, jbd2_update_log_tail() called by
     231             :                          * jbd2_journal_commit_transaction() may also take
     232             :                          * checkpoint_mutex.  So we need to temporarily
     233             :                          * drop it.
     234             :                          */
     235           0 :                         mutex_unlock(&journal->j_checkpoint_mutex);
     236           0 :                         jbd2_log_wait_commit(journal, tid);
     237           0 :                         mutex_lock_io(&journal->j_checkpoint_mutex);
     238           0 :                         spin_lock(&journal->j_list_lock);
     239           0 :                         goto restart;
     240             :                 }
     241           0 :                 if (!trylock_buffer(bh)) {
     242             :                         /*
     243             :                          * The buffer is locked, it may be writing back, or
     244             :                          * flushing out in the last couple of cycles, or
     245             :                          * re-adding into a new transaction, need to check
     246             :                          * it again until it's unlocked.
     247             :                          */
     248           0 :                         get_bh(bh);
     249           0 :                         spin_unlock(&journal->j_list_lock);
     250           0 :                         wait_on_buffer(bh);
     251             :                         /* the journal_head may have gone by now */
     252           0 :                         BUFFER_TRACE(bh, "brelse");
     253           0 :                         __brelse(bh);
     254           0 :                         goto retry;
     255           0 :                 } else if (!buffer_dirty(bh)) {
     256           0 :                         unlock_buffer(bh);
     257           0 :                         BUFFER_TRACE(bh, "remove from checkpoint");
     258             :                         /*
     259             :                          * If the transaction was released or the checkpoint
     260             :                          * list was empty, we're done.
     261             :                          */
     262           0 :                         if (__jbd2_journal_remove_checkpoint(jh) ||
     263           0 :                             !transaction->t_checkpoint_list)
     264           0 :                                 goto out;
     265             :                 } else {
     266           0 :                         unlock_buffer(bh);
     267             :                         /*
     268             :                          * We are about to write the buffer, it could be
     269             :                          * raced by some other transaction shrink or buffer
     270             :                          * re-log logic once we release the j_list_lock,
     271             :                          * leave it on the checkpoint list and check status
     272             :                          * again to make sure it's clean.
     273             :                          */
     274           0 :                         BUFFER_TRACE(bh, "queue");
     275           0 :                         get_bh(bh);
     276           0 :                         J_ASSERT_BH(bh, !buffer_jwrite(bh));
     277           0 :                         journal->j_chkpt_bhs[batch_count++] = bh;
     278           0 :                         transaction->t_chp_stats.cs_written++;
     279           0 :                         transaction->t_checkpoint_list = jh->b_cpnext;
     280             :                 }
     281             : 
     282           0 :                 if ((batch_count == JBD2_NR_BATCH) ||
     283           0 :                     need_resched() || spin_needbreak(&journal->j_list_lock) ||
     284           0 :                     jh2bh(transaction->t_checkpoint_list) == journal->j_chkpt_bhs[0])
     285           0 :                         goto unlock_and_flush;
     286             :         }
     287             : 
     288           0 :         if (batch_count) {
     289           0 :                 unlock_and_flush:
     290           0 :                         spin_unlock(&journal->j_list_lock);
     291           0 :                 retry:
     292           0 :                         if (batch_count)
     293           0 :                                 __flush_batch(journal, &batch_count);
     294           0 :                         spin_lock(&journal->j_list_lock);
     295           0 :                         goto restart;
     296             :         }
     297             : 
     298           0 : out:
     299           0 :         spin_unlock(&journal->j_list_lock);
     300           0 :         result = jbd2_cleanup_journal_tail(journal);
     301             : 
     302           0 :         return (result < 0) ? result : 0;
     303             : }
     304             : 
     305             : /*
     306             :  * Check the list of checkpoint transactions for the journal to see if
     307             :  * we have already got rid of any since the last update of the log tail
     308             :  * in the journal superblock.  If so, we can instantly roll the
     309             :  * superblock forward to remove those transactions from the log.
     310             :  *
     311             :  * Return <0 on error, 0 on success, 1 if there was nothing to clean up.
     312             :  *
     313             :  * Called with the journal lock held.
     314             :  *
     315             :  * This is the only part of the journaling code which really needs to be
     316             :  * aware of transaction aborts.  Checkpointing involves writing to the
     317             :  * main filesystem area rather than to the journal, so it can proceed
     318             :  * even in abort state, but we must not update the super block if
     319             :  * checkpointing may have failed.  Otherwise, we would lose some metadata
     320             :  * buffers which should be written-back to the filesystem.
     321             :  */
     322             : 
     323           0 : int jbd2_cleanup_journal_tail(journal_t *journal)
     324             : {
     325           0 :         tid_t           first_tid;
     326           0 :         unsigned long   blocknr;
     327             : 
     328           0 :         if (is_journal_aborted(journal))
     329             :                 return -EIO;
     330             : 
     331           0 :         if (!jbd2_journal_get_log_tail(journal, &first_tid, &blocknr))
     332             :                 return 1;
     333           0 :         J_ASSERT(blocknr != 0);
     334             : 
     335             :         /*
     336             :          * We need to make sure that any blocks that were recently written out
     337             :          * --- perhaps by jbd2_log_do_checkpoint() --- are flushed out before
     338             :          * we drop the transactions from the journal. It's unlikely this will
     339             :          * be necessary, especially with an appropriately sized journal, but we
     340             :          * need this to guarantee correctness.  Fortunately
     341             :          * jbd2_cleanup_journal_tail() doesn't get called all that often.
     342             :          */
     343           0 :         if (journal->j_flags & JBD2_BARRIER)
     344           0 :                 blkdev_issue_flush(journal->j_fs_dev);
     345             : 
     346           0 :         return __jbd2_update_log_tail(journal, first_tid, blocknr);
     347             : }
     348             : 
     349             : 
     350             : /* Checkpoint list management */
     351             : 
     352             : /*
     353             :  * journal_shrink_one_cp_list
     354             :  *
     355             :  * Find all the written-back checkpoint buffers in the given list
     356             :  * and try to release them. If the whole transaction is released, set
     357             :  * the 'released' parameter. Return the number of released checkpointed
     358             :  * buffers.
     359             :  *
     360             :  * Called with j_list_lock held.
     361             :  */
     362           0 : static unsigned long journal_shrink_one_cp_list(struct journal_head *jh,
     363             :                                                 bool destroy, bool *released)
     364             : {
     365           0 :         struct journal_head *last_jh;
     366           0 :         struct journal_head *next_jh = jh;
     367           0 :         unsigned long nr_freed = 0;
     368           0 :         int ret;
     369             : 
     370           0 :         *released = false;
     371           0 :         if (!jh)
     372             :                 return 0;
     373             : 
     374           0 :         last_jh = jh->b_cpprev;
     375           0 :         do {
     376           0 :                 jh = next_jh;
     377           0 :                 next_jh = jh->b_cpnext;
     378             : 
     379           0 :                 if (destroy) {
     380           0 :                         ret = __jbd2_journal_remove_checkpoint(jh);
     381             :                 } else {
     382           0 :                         ret = jbd2_journal_try_remove_checkpoint(jh);
     383           0 :                         if (ret < 0)
     384           0 :                                 continue;
     385             :                 }
     386             : 
     387           0 :                 nr_freed++;
     388           0 :                 if (ret) {
     389           0 :                         *released = true;
     390           0 :                         break;
     391             :                 }
     392             : 
     393           0 :                 if (need_resched())
     394             :                         break;
     395           0 :         } while (jh != last_jh);
     396             : 
     397             :         return nr_freed;
     398             : }
     399             : 
     400             : /*
     401             :  * jbd2_journal_shrink_checkpoint_list
     402             :  *
     403             :  * Find 'nr_to_scan' written-back checkpoint buffers in the journal
     404             :  * and try to release them. Return the number of released checkpointed
     405             :  * buffers.
     406             :  *
     407             :  * Called with j_list_lock held.
     408             :  */
     409           0 : unsigned long jbd2_journal_shrink_checkpoint_list(journal_t *journal,
     410             :                                                   unsigned long *nr_to_scan)
     411             : {
     412           0 :         transaction_t *transaction, *last_transaction, *next_transaction;
     413           0 :         bool __maybe_unused released;
     414           0 :         tid_t first_tid = 0, last_tid = 0, next_tid = 0;
     415           0 :         tid_t tid = 0;
     416           0 :         unsigned long nr_freed = 0;
     417           0 :         unsigned long freed;
     418             : 
     419           0 : again:
     420           0 :         spin_lock(&journal->j_list_lock);
     421           0 :         if (!journal->j_checkpoint_transactions) {
     422           0 :                 spin_unlock(&journal->j_list_lock);
     423           0 :                 goto out;
     424             :         }
     425             : 
     426             :         /*
     427             :          * Get next shrink transaction, resume previous scan or start
     428             :          * over again. If some others do checkpoint and drop transaction
     429             :          * from the checkpoint list, we ignore saved j_shrink_transaction
     430             :          * and start over unconditionally.
     431             :          */
     432           0 :         if (journal->j_shrink_transaction)
     433             :                 transaction = journal->j_shrink_transaction;
     434             :         else
     435           0 :                 transaction = journal->j_checkpoint_transactions;
     436             : 
     437           0 :         if (!first_tid)
     438           0 :                 first_tid = transaction->t_tid;
     439           0 :         last_transaction = journal->j_checkpoint_transactions->t_cpprev;
     440           0 :         next_transaction = transaction;
     441           0 :         last_tid = last_transaction->t_tid;
     442           0 :         do {
     443           0 :                 transaction = next_transaction;
     444           0 :                 next_transaction = transaction->t_cpnext;
     445           0 :                 tid = transaction->t_tid;
     446             : 
     447           0 :                 freed = journal_shrink_one_cp_list(transaction->t_checkpoint_list,
     448             :                                                    false, &released);
     449           0 :                 nr_freed += freed;
     450           0 :                 (*nr_to_scan) -= min(*nr_to_scan, freed);
     451           0 :                 if (*nr_to_scan == 0)
     452             :                         break;
     453           0 :                 if (need_resched() || spin_needbreak(&journal->j_list_lock))
     454             :                         break;
     455           0 :         } while (transaction != last_transaction);
     456             : 
     457           0 :         if (transaction != last_transaction) {
     458           0 :                 journal->j_shrink_transaction = next_transaction;
     459           0 :                 next_tid = next_transaction->t_tid;
     460             :         } else {
     461           0 :                 journal->j_shrink_transaction = NULL;
     462           0 :                 next_tid = 0;
     463             :         }
     464             : 
     465           0 :         spin_unlock(&journal->j_list_lock);
     466           0 :         cond_resched();
     467             : 
     468           0 :         if (*nr_to_scan && next_tid)
     469           0 :                 goto again;
     470           0 : out:
     471           0 :         trace_jbd2_shrink_checkpoint_list(journal, first_tid, tid, last_tid,
     472             :                                           nr_freed, next_tid);
     473             : 
     474           0 :         return nr_freed;
     475             : }
     476             : 
     477             : /*
     478             :  * journal_clean_checkpoint_list
     479             :  *
     480             :  * Find all the written-back checkpoint buffers in the journal and release them.
     481             :  * If 'destroy' is set, release all buffers unconditionally.
     482             :  *
     483             :  * Called with j_list_lock held.
     484             :  */
     485           0 : void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy)
     486             : {
     487           0 :         transaction_t *transaction, *last_transaction, *next_transaction;
     488           0 :         bool released;
     489             : 
     490           0 :         transaction = journal->j_checkpoint_transactions;
     491           0 :         if (!transaction)
     492           0 :                 return;
     493             : 
     494           0 :         last_transaction = transaction->t_cpprev;
     495           0 :         next_transaction = transaction;
     496           0 :         do {
     497           0 :                 transaction = next_transaction;
     498           0 :                 next_transaction = transaction->t_cpnext;
     499           0 :                 journal_shrink_one_cp_list(transaction->t_checkpoint_list,
     500             :                                            destroy, &released);
     501             :                 /*
     502             :                  * This function only frees up some memory if possible so we
     503             :                  * dont have an obligation to finish processing. Bail out if
     504             :                  * preemption requested:
     505             :                  */
     506           0 :                 if (need_resched())
     507             :                         return;
     508             :                 /*
     509             :                  * Stop scanning if we couldn't free the transaction. This
     510             :                  * avoids pointless scanning of transactions which still
     511             :                  * weren't checkpointed.
     512             :                  */
     513           0 :                 if (!released)
     514             :                         return;
     515           0 :         } while (transaction != last_transaction);
     516             : }
     517             : 
     518             : /*
     519             :  * Remove buffers from all checkpoint lists as journal is aborted and we just
     520             :  * need to free memory
     521             :  */
     522           0 : void jbd2_journal_destroy_checkpoint(journal_t *journal)
     523             : {
     524             :         /*
     525             :          * We loop because __jbd2_journal_clean_checkpoint_list() may abort
     526             :          * early due to a need of rescheduling.
     527             :          */
     528           0 :         while (1) {
     529           0 :                 spin_lock(&journal->j_list_lock);
     530           0 :                 if (!journal->j_checkpoint_transactions) {
     531           0 :                         spin_unlock(&journal->j_list_lock);
     532           0 :                         break;
     533             :                 }
     534           0 :                 __jbd2_journal_clean_checkpoint_list(journal, true);
     535           0 :                 spin_unlock(&journal->j_list_lock);
     536           0 :                 cond_resched();
     537             :         }
     538           0 : }
     539             : 
     540             : /*
     541             :  * journal_remove_checkpoint: called after a buffer has been committed
     542             :  * to disk (either by being write-back flushed to disk, or being
     543             :  * committed to the log).
     544             :  *
     545             :  * We cannot safely clean a transaction out of the log until all of the
     546             :  * buffer updates committed in that transaction have safely been stored
     547             :  * elsewhere on disk.  To achieve this, all of the buffers in a
     548             :  * transaction need to be maintained on the transaction's checkpoint
     549             :  * lists until they have been rewritten, at which point this function is
     550             :  * called to remove the buffer from the existing transaction's
     551             :  * checkpoint lists.
     552             :  *
     553             :  * The function returns 1 if it frees the transaction, 0 otherwise.
     554             :  * The function can free jh and bh.
     555             :  *
     556             :  * This function is called with j_list_lock held.
     557             :  */
     558           0 : int __jbd2_journal_remove_checkpoint(struct journal_head *jh)
     559             : {
     560           0 :         struct transaction_chp_stats_s *stats;
     561           0 :         transaction_t *transaction;
     562           0 :         journal_t *journal;
     563           0 :         struct buffer_head *bh = jh2bh(jh);
     564             : 
     565           0 :         JBUFFER_TRACE(jh, "entry");
     566             : 
     567           0 :         transaction = jh->b_cp_transaction;
     568           0 :         if (!transaction) {
     569             :                 JBUFFER_TRACE(jh, "not on transaction");
     570             :                 return 0;
     571             :         }
     572           0 :         journal = transaction->t_journal;
     573             : 
     574           0 :         JBUFFER_TRACE(jh, "removing from transaction");
     575             : 
     576             :         /*
     577             :          * If we have failed to write the buffer out to disk, the filesystem
     578             :          * may become inconsistent. We cannot abort the journal here since
     579             :          * we hold j_list_lock and we have to be careful about races with
     580             :          * jbd2_journal_destroy(). So mark the writeback IO error in the
     581             :          * journal here and we abort the journal later from a better context.
     582             :          */
     583           0 :         if (buffer_write_io_error(bh))
     584           0 :                 set_bit(JBD2_CHECKPOINT_IO_ERROR, &journal->j_atomic_flags);
     585             : 
     586           0 :         __buffer_unlink(jh);
     587           0 :         jh->b_cp_transaction = NULL;
     588           0 :         percpu_counter_dec(&journal->j_checkpoint_jh_count);
     589           0 :         jbd2_journal_put_journal_head(jh);
     590             : 
     591             :         /* Is this transaction empty? */
     592           0 :         if (transaction->t_checkpoint_list)
     593             :                 return 0;
     594             : 
     595             :         /*
     596             :          * There is one special case to worry about: if we have just pulled the
     597             :          * buffer off a running or committing transaction's checkpoing list,
     598             :          * then even if the checkpoint list is empty, the transaction obviously
     599             :          * cannot be dropped!
     600             :          *
     601             :          * The locking here around t_state is a bit sleazy.
     602             :          * See the comment at the end of jbd2_journal_commit_transaction().
     603             :          */
     604           0 :         if (transaction->t_state != T_FINISHED)
     605             :                 return 0;
     606             : 
     607             :         /*
     608             :          * OK, that was the last buffer for the transaction, we can now
     609             :          * safely remove this transaction from the log.
     610             :          */
     611           0 :         stats = &transaction->t_chp_stats;
     612           0 :         if (stats->cs_chp_time)
     613           0 :                 stats->cs_chp_time = jbd2_time_diff(stats->cs_chp_time,
     614             :                                                     jiffies);
     615           0 :         trace_jbd2_checkpoint_stats(journal->j_fs_dev->bd_dev,
     616             :                                     transaction->t_tid, stats);
     617             : 
     618           0 :         __jbd2_journal_drop_transaction(journal, transaction);
     619           0 :         jbd2_journal_free_transaction(transaction);
     620           0 :         return 1;
     621             : }
     622             : 
     623             : /*
     624             :  * Check the checkpoint buffer and try to remove it from the checkpoint
     625             :  * list if it's clean. Returns -EBUSY if it is not clean, returns 1 if
     626             :  * it frees the transaction, 0 otherwise.
     627             :  *
     628             :  * This function is called with j_list_lock held.
     629             :  */
     630           0 : int jbd2_journal_try_remove_checkpoint(struct journal_head *jh)
     631             : {
     632           0 :         struct buffer_head *bh = jh2bh(jh);
     633             : 
     634           0 :         if (!trylock_buffer(bh))
     635             :                 return -EBUSY;
     636           0 :         if (buffer_dirty(bh)) {
     637           0 :                 unlock_buffer(bh);
     638           0 :                 return -EBUSY;
     639             :         }
     640           0 :         unlock_buffer(bh);
     641             : 
     642             :         /*
     643             :          * Buffer is clean and the IO has finished (we held the buffer
     644             :          * lock) so the checkpoint is done. We can safely remove the
     645             :          * buffer from this transaction.
     646             :          */
     647           0 :         JBUFFER_TRACE(jh, "remove from checkpoint list");
     648           0 :         return __jbd2_journal_remove_checkpoint(jh);
     649             : }
     650             : 
     651             : /*
     652             :  * journal_insert_checkpoint: put a committed buffer onto a checkpoint
     653             :  * list so that we know when it is safe to clean the transaction out of
     654             :  * the log.
     655             :  *
     656             :  * Called with the journal locked.
     657             :  * Called with j_list_lock held.
     658             :  */
     659           0 : void __jbd2_journal_insert_checkpoint(struct journal_head *jh,
     660             :                                transaction_t *transaction)
     661             : {
     662           0 :         JBUFFER_TRACE(jh, "entry");
     663           0 :         J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh)));
     664           0 :         J_ASSERT_JH(jh, jh->b_cp_transaction == NULL);
     665             : 
     666             :         /* Get reference for checkpointing transaction */
     667           0 :         jbd2_journal_grab_journal_head(jh2bh(jh));
     668           0 :         jh->b_cp_transaction = transaction;
     669             : 
     670           0 :         if (!transaction->t_checkpoint_list) {
     671           0 :                 jh->b_cpnext = jh->b_cpprev = jh;
     672             :         } else {
     673           0 :                 jh->b_cpnext = transaction->t_checkpoint_list;
     674           0 :                 jh->b_cpprev = transaction->t_checkpoint_list->b_cpprev;
     675           0 :                 jh->b_cpprev->b_cpnext = jh;
     676           0 :                 jh->b_cpnext->b_cpprev = jh;
     677             :         }
     678           0 :         transaction->t_checkpoint_list = jh;
     679           0 :         percpu_counter_inc(&transaction->t_journal->j_checkpoint_jh_count);
     680           0 : }
     681             : 
     682             : /*
     683             :  * We've finished with this transaction structure: adios...
     684             :  *
     685             :  * The transaction must have no links except for the checkpoint by this
     686             :  * point.
     687             :  *
     688             :  * Called with the journal locked.
     689             :  * Called with j_list_lock held.
     690             :  */
     691             : 
     692           0 : void __jbd2_journal_drop_transaction(journal_t *journal, transaction_t *transaction)
     693             : {
     694           0 :         assert_spin_locked(&journal->j_list_lock);
     695             : 
     696           0 :         journal->j_shrink_transaction = NULL;
     697           0 :         if (transaction->t_cpnext) {
     698           0 :                 transaction->t_cpnext->t_cpprev = transaction->t_cpprev;
     699           0 :                 transaction->t_cpprev->t_cpnext = transaction->t_cpnext;
     700           0 :                 if (journal->j_checkpoint_transactions == transaction)
     701           0 :                         journal->j_checkpoint_transactions =
     702             :                                 transaction->t_cpnext;
     703           0 :                 if (journal->j_checkpoint_transactions == transaction)
     704           0 :                         journal->j_checkpoint_transactions = NULL;
     705             :         }
     706             : 
     707           0 :         J_ASSERT(transaction->t_state == T_FINISHED);
     708           0 :         J_ASSERT(transaction->t_buffers == NULL);
     709           0 :         J_ASSERT(transaction->t_forget == NULL);
     710           0 :         J_ASSERT(transaction->t_shadow_list == NULL);
     711           0 :         J_ASSERT(transaction->t_checkpoint_list == NULL);
     712           0 :         J_ASSERT(atomic_read(&transaction->t_updates) == 0);
     713           0 :         J_ASSERT(journal->j_committing_transaction != transaction);
     714           0 :         J_ASSERT(journal->j_running_transaction != transaction);
     715             : 
     716           0 :         trace_jbd2_drop_transaction(journal, transaction);
     717             : 
     718           0 :         jbd2_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
     719           0 : }

Generated by: LCOV version 1.14