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 | 1582 | static inline unsigned long jbd2_log_space_left(journal_t *journal) |
| 1583 | 1583 | { |
| 1584 | 1584 | /* Allow for rounding errors */ |
| 1585 | − unsigned long free = journal->j_free - 32; | |
| 1585 | + long free = journal->j_free - 32; | |
| 1586 | 1586 | |
| 1587 | 1587 | if (journal->j_committing_transaction) { |
| 1588 | 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 | 1591 | /* Transaction + control blocks */ |
| 1592 | 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 | /* |