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.
Showing the changes to include/linux (1 of 4 files). Show all
Unified · Split
| @@ -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 transaction | 684 | * 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 journal | 1566 | * 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 | */ |
| 1573 | static inline int jbd2_space_needed(journal_t *journal) | 1569 | static 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 | } |