From: Alex Tomas during truncate ext3 calls journal_forget() for freed blocks, but before these blocks go to the transaction and jbd reserves space in log for them (->t_outstanding_credits). also, journal_forget() removes these blocks from the transaction, but doesn't correct log space reservation. for example, removal of 500MB file reserves 136 blocks, but only 10 blocks go to the log. a commit is expensive and correct reservation allows us to avoid needless commits. here is the patch. tested on UP. Signed-off-by: Alex Tomas Signed-off-by: Andrew Morton --- 25-akpm/fs/jbd/transaction.c | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletion(-) diff -puN fs/jbd/transaction.c~jbd-log-space-management-optimization fs/jbd/transaction.c --- 25/fs/jbd/transaction.c~jbd-log-space-management-optimization 2005-01-22 18:25:15.876117872 -0800 +++ 25-akpm/fs/jbd/transaction.c 2005-01-22 18:27:20.439181408 -0800 @@ -1258,6 +1258,7 @@ int journal_forget (handle_t *handle, st transaction_t *transaction = handle->h_transaction; journal_t *journal = transaction->t_journal; struct journal_head *jh; + int drop_reserve = 0; int err = 0; BUFFER_TRACE(bh, "entry"); @@ -1289,6 +1290,7 @@ int journal_forget (handle_t *handle, st JBUFFER_TRACE(jh, "belongs to current transaction: unfile"); __journal_unfile_buffer(jh); + drop_reserve = 1; /* * We are no longer going to journal this buffer. @@ -1311,7 +1313,8 @@ int journal_forget (handle_t *handle, st spin_unlock(&journal->j_list_lock); jbd_unlock_bh_state(bh); __bforget(bh); - return 0; + err = 0; + goto drop; } } } else if (jh->b_transaction) { @@ -1326,6 +1329,7 @@ int journal_forget (handle_t *handle, st if (jh->b_next_transaction) { J_ASSERT(jh->b_next_transaction == transaction); jh->b_next_transaction = NULL; + drop_reserve = 1; } } @@ -1333,6 +1337,13 @@ not_jbd: spin_unlock(&journal->j_list_lock); jbd_unlock_bh_state(bh); __brelse(bh); +drop: + if (drop_reserve) { + /* no need to reserve log space for this block -bzzz */ + spin_lock(&transaction->t_handle_lock); + transaction->t_outstanding_credits--; + spin_unlock(&transaction->t_handle_lock); + } return err; } _