Allow truncate to discard unmapped buffers
PATCH 3/10 Allow truncate to discard unmapped buffers
The buffer state "uptodate, dirty, unmapped" is legal. It occurs when a mapped page with attached buffers which is over a hole is dirtied.
So discard_buffer() needs to be able to discard those buffers as well; otherwise the page ends up clean, with dirty buffers and is unfreeable.
=====================================
fs/buffer.c renamed from fs/buffer.c~truncate-leak +8 -10
@@ -1091,17 +1091,15 @@ EXPORT_SYMBOL(set_bh_page);/* * Called when truncating a buffer on a page completely. */ -static void discard_buffer (struct buffer_head * bh) +static /* inline */ void discard_buffer (struct buffer_head * bh) { -if (buffer_mapped (bh)) { -clear_buffer_dirty (bh); -lock_buffer (bh); - bh->b_bdev =NULL ; -clear_buffer_mapped (bh); -clear_buffer_req (bh); -clear_buffer_new (bh); -unlock_buffer (bh); - } +lock_buffer (bh); +clear_buffer_dirty (bh); + bh->b_bdev =NULL ; +clear_buffer_mapped (bh); +clear_buffer_req (bh); +clear_buffer_new (bh); +unlock_buffer (bh); }/**
fs/jbd/transaction.c renamed from fs/jbd/transaction.c~truncate-leak +1 -4
@@ -1587,7 +1587,7 @@ static int __journal_try_to_free_buffer( goto out; } -if (!buffer_uptodate (bh)) +if (!buffer_uptodate (bh))/* AKPM: why? */ goto out;if (jh->b_next_transaction !=0 )
@@ -1775,9 +1775,6 @@ static int journal_unmap_buffer(journal_BUFFER_TRACE (bh,"entry" ); -if (!buffer_mapped (bh)) -return 1 ; -/* It is safe to proceed here without the * journal_datalist_spinlock because the buffers cannot be * stolen by try_to_free_buffers as long as we are holding the