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 | 10 +++++++++- 1 files changed, 9 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-02-02 15:36:00.597124576 -0800 +++ 25-akpm/fs/jbd/transaction.c 2005-02-02 15:36:00.603123664 -0800 @@ -1187,6 +1187,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"); @@ -1224,6 +1225,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. @@ -1246,7 +1248,7 @@ int journal_forget (handle_t *handle, st spin_unlock(&journal->j_list_lock); jbd_unlock_bh_state(bh); __bforget(bh); - return 0; + goto drop; } } } else if (jh->b_transaction) { @@ -1261,6 +1263,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; } } @@ -1268,6 +1271,11 @@ 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 */ + handle->h_buffer_credits++; + } return err; } _