When number of free space in the journal is very low, the arithmetic in jbd2_log_space_left() could underflow resulting in very high number of free blocks and thus triggering assertion failure in transaction commit code complaining there's not enough space in the journal: J_ASSERT(journal->j_free > 1); Properly check for the low number of free blocks.
Showing the changes to include/linux (1 of 1 file). Show all
Unified · Split
| @@ -1582,7 +1582,7 @@ static inline int jbd2_space_needed(journal_t *journal) · 1581 unmodified lines | |||
| 1582 | static inline unsigned long jbd2_log_space_left(journal_t *journal) | 1582 | static inline unsigned long jbd2_log_space_left(journal_t *journal) |
| 1583 | { | 1583 | { |
| 1584 | /* Allow for rounding errors */ | 1584 | /* Allow for rounding errors */ |
| 1585 | unsigned long free = journal->j_free - 32; | 1585 | long free = journal->j_free - 32; |
| 1586 | 1586 | ||
| 1587 | if (journal->j_committing_transaction) { | 1587 | if (journal->j_committing_transaction) { |
| 1588 | unsigned long committing = atomic_read(&journal-> | 1588 | unsigned long committing = atomic_read(&journal-> |
| @@ -1591,7 +1591,7 @@ static inline unsigned long jbd2_log_space_left(journal_t *journal) · 2 unmodified lines | |||
| 1591 | /* Transaction + control blocks */ | 1591 | /* Transaction + control blocks */ |
| 1592 | free -= committing + (committing >> JBD2_CONTROL_BLOCKS_SHIFT); | 1592 | free -= committing + (committing >> JBD2_CONTROL_BLOCKS_SHIFT); |
| 1593 | } | 1593 | } |
| 1594 | return free; | 1594 | return max_t(long, free, 0); |
| 1595 | } | 1595 | } |
| 1596 | 1596 | ||
| 1597 | /* | 1597 | /* |