History

jbd2: Account descriptor blocks into t_outstanding_credits

Currently, journal descriptor blocks were not accounted in transaction->t_outstanding_credits and we were just leaving some slack space in the journal for them (in jbd2_log_space_left() and jbd2_space_needed()). This is making proper accounting (and reservation we want to add) of descriptor blocks difficult so switch to accounting descriptor blocks in transaction->t_outstanding_credits and just reserve the same amount of credits in t_outstanding credits for journal descriptor blocks when creating transaction.

Jan Kara committed 7 years ago

Commit 9f356e51 parent ec8b6f64 files · +24 −25Browse files

Unified · Split

4 files
  1. fs/jbd2/commit.c +4 −2
  2. fs/jbd2/journal.c +1 −0
  3. fs/jbd2/transaction.c +12 −8
  4. include/linux/jbd2.h +7 −15
fs/jbd2/commit.c+4−2
@@ -560,8 +560,7 @@ void jbd2_journal_commit_transaction(journal_t *journal) · 559 unmodified lines
560 stats.run.rs_logging = jiffies;560 stats.run.rs_logging = jiffies;
561 stats.run.rs_flushing = jbd2_time_diff(stats.run.rs_flushing,561 stats.run.rs_flushing = jbd2_time_diff(stats.run.rs_flushing,
562 stats.run.rs_logging);562 stats.run.rs_logging);
563 stats.run.rs_blocks =563 stats.run.rs_blocks = commit_transaction->t_nr_buffers;
564 atomic_read(&commit_transaction->t_outstanding_credits);
565 stats.run.rs_blocks_logged = 0;564 stats.run.rs_blocks_logged = 0;
566 565
567 J_ASSERT(commit_transaction->t_nr_buffers <=566 J_ASSERT(commit_transaction->t_nr_buffers <=
@@ -889,6 +888,9 @@ start_journal_io: · 321 unmodified lines
889 if (err)888 if (err)
890 jbd2_journal_abort(journal, err);889 jbd2_journal_abort(journal, err);
891 890
891 WARN_ON_ONCE(
892 atomic_read(&commit_transaction->t_outstanding_credits) < 0);
893
892 /*894 /*
893 * Now disk caches for filesystem device are flushed so we are safe to895 * Now disk caches for filesystem device are flushed so we are safe to
894 * erase checkpointed transactions from the log by updating journal896 * erase checkpointed transactions from the log by updating journal
fs/jbd2/journal.c+1−0
@@ -840,6 +840,7 @@ jbd2_journal_get_descriptor_buffer(transaction_t *transaction, int type) · 839 unmodified lines
840 bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);840 bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize);
841 if (!bh)841 if (!bh)
842 return NULL;842 return NULL;
843 atomic_dec(&transaction->t_outstanding_credits);
843 lock_buffer(bh);844 lock_buffer(bh);
844 memset(bh->b_data, 0, journal->j_blocksize);845 memset(bh->b_data, 0, journal->j_blocksize);
845 header = (journal_header_t *)bh->b_data;846 header = (journal_header_t *)bh->b_data;
fs/jbd2/transaction.c+12−8
@@ -62,6 +62,17 @@ void jbd2_journal_free_transaction(transaction_t *transaction) · 61 unmodified lines
62 kmem_cache_free(transaction_cache, transaction);62 kmem_cache_free(transaction_cache, transaction);
63}63}
64 64
65/*
66 * We reserve t_outstanding_credits >> JBD2_CONTROL_BLOCKS_SHIFT for
67 * transaction descriptor blocks.
68 */
69#define JBD2_CONTROL_BLOCKS_SHIFT 5
70
71static int jbd2_descriptor_blocks_per_trans(journal_t *journal)
72{
73 return journal->j_max_transaction_buffers >> JBD2_CONTROL_BLOCKS_SHIFT;
74}
75
65/*76/*
66 * jbd2_get_transaction: obtain a new transaction_t object.77 * jbd2_get_transaction: obtain a new transaction_t object.
67 *78 *
@@ -88,6 +99,7 @@ static void jbd2_get_transaction(journal_t *journal, · 20 unmodified lines
88 spin_lock_init(&transaction->t_handle_lock);99 spin_lock_init(&transaction->t_handle_lock);
89 atomic_set(&transaction->t_updates, 0);100 atomic_set(&transaction->t_updates, 0);
90 atomic_set(&transaction->t_outstanding_credits,101 atomic_set(&transaction->t_outstanding_credits,
102 jbd2_descriptor_blocks_per_trans(journal) +
91 atomic_read(&journal->j_reserved_credits));103 atomic_read(&journal->j_reserved_credits));
92 atomic_set(&transaction->t_handle_count, 0);104 atomic_set(&transaction->t_handle_count, 0);
93 INIT_LIST_HEAD(&transaction->t_inode_list);105 INIT_LIST_HEAD(&transaction->t_inode_list);
@@ -634,14 +646,6 @@ int jbd2_journal_extend(handle_t *handle, int nblocks) · 540 unmodified lines
634 goto unlock;646 goto unlock;
635 }647 }
636 648
637 if (wanted + (wanted >> JBD2_CONTROL_BLOCKS_SHIFT) >
638 jbd2_log_space_left(journal)) {
639 jbd_debug(3, "denied handle %p %d blocks: "
640 "insufficient log space\n", handle, nblocks);
641 atomic_sub(nblocks, &transaction->t_outstanding_credits);
642 goto unlock;
643 }
644
645 trace_jbd2_handle_extend(journal->j_fs_dev->bd_dev,649 trace_jbd2_handle_extend(journal->j_fs_dev->bd_dev,
646 transaction->t_tid,650 transaction->t_tid,
647 handle->h_type, handle->h_line_no,651 handle->h_type, handle->h_line_no,
include/linux/jbd2.h+7−15
@@ -681,8 +681,10 @@ struct transaction_s · 680 unmodified lines
681 atomic_t t_updates;681 atomic_t t_updates;
682 682
683 /*683 /*
684 * Number of buffers reserved for use by all handles in this transaction684 * Number of blocks reserved for this transaction in the journal.
685 * handle but not yet modified. [none]685 * This is including all credits reserved when starting transaction
686 * handles as well as all journal descriptor blocks needed for this
687 * transaction. [none]
686 */688 */
687 atomic_t t_outstanding_credits;689 atomic_t t_outstanding_credits;
688 690
@@ -1560,20 +1562,13 @@ static inline int jbd2_journal_has_csum_v2or3(journal_t *journal) · 871 unmodified lines
1560 return journal->j_chksum_driver != NULL;1562 return journal->j_chksum_driver != NULL;
1561}1563}
1562 1564
1563/*
1564 * We reserve t_outstanding_credits >> JBD2_CONTROL_BLOCKS_SHIFT for
1565 * transaction control blocks.
1566 */
1567#define JBD2_CONTROL_BLOCKS_SHIFT 5
1568
1569/*1565/*
1570 * Return the minimum number of blocks which must be free in the journal1566 * Return the minimum number of blocks which must be free in the journal
1571 * before a new transaction may be started. Must be called under j_state_lock.1567 * before a new transaction may be started. Must be called under j_state_lock.
1572 */1568 */
1573static inline int jbd2_space_needed(journal_t *journal)1569static inline int jbd2_space_needed(journal_t *journal)
1574{1570{
1575 int nblocks = journal->j_max_transaction_buffers;1571 return journal->j_max_transaction_buffers;
1576 return nblocks + (nblocks >> JBD2_CONTROL_BLOCKS_SHIFT);
1577}1572}
1578 1573
1579/*1574/*
@@ -1585,11 +1580,8 @@ static inline unsigned long jbd2_log_space_left(journal_t *journal) · 5 unmodified lines
1585 long free = journal->j_free - 32;1580 long free = journal->j_free - 32;
1586 1581
1587 if (journal->j_committing_transaction) {1582 if (journal->j_committing_transaction) {
1588 unsigned long committing = atomic_read(&journal->1583 free -= atomic_read(&journal->
1589 j_committing_transaction->t_outstanding_credits);1584 j_committing_transaction->t_outstanding_credits);
1590
1591 /* Transaction + control blocks */
1592 free -= committing + (committing >> JBD2_CONTROL_BLOCKS_SHIFT);
1593 }1585 }
1594 return max_t(long, free, 0);1586 return max_t(long, free, 0);
1595}1587}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t