[PATCH] Fix try_to_free_buffer() locking
Fix commit ecdfc9787f
Not to put too fine a point on it, but in a nutshell...
__set_page_dirty_buffers() | try_to_free_buffers()
---------------------------+---------------------------
| spin_lock(private_lock);
| drop_bufers()
| spin_unlock(private_lock);
spin_lock(private_lock) |
!page_has_buffers() |
spin_unlock(private_lock) |
SetPageDirty() |
| cancel_dirty_page()
oops!
Signed-off-by: Nick Piggin <npiggin@suse.de>
Acked-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
4cbf2aa35e
commit
87df7241bd
@ -2844,7 +2844,6 @@ int try_to_free_buffers(struct page *page)
|
|||||||
|
|
||||||
spin_lock(&mapping->private_lock);
|
spin_lock(&mapping->private_lock);
|
||||||
ret = drop_buffers(page, &buffers_to_free);
|
ret = drop_buffers(page, &buffers_to_free);
|
||||||
spin_unlock(&mapping->private_lock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the filesystem writes its buffers by hand (eg ext3)
|
* If the filesystem writes its buffers by hand (eg ext3)
|
||||||
@ -2855,9 +2854,14 @@ int try_to_free_buffers(struct page *page)
|
|||||||
* Also, during truncate, discard_buffer will have marked all
|
* Also, during truncate, discard_buffer will have marked all
|
||||||
* the page's buffers clean. We discover that here and clean
|
* the page's buffers clean. We discover that here and clean
|
||||||
* the page also.
|
* the page also.
|
||||||
|
*
|
||||||
|
* private_lock must be held over this entire operation in order
|
||||||
|
* to synchronise against __set_page_dirty_buffers and prevent the
|
||||||
|
* dirty bit from being lost.
|
||||||
*/
|
*/
|
||||||
if (ret)
|
if (ret)
|
||||||
cancel_dirty_page(page, PAGE_CACHE_SIZE);
|
cancel_dirty_page(page, PAGE_CACHE_SIZE);
|
||||||
|
spin_unlock(&mapping->private_lock);
|
||||||
out:
|
out:
|
||||||
if (buffers_to_free) {
|
if (buffers_to_free) {
|
||||||
struct buffer_head *bh = buffers_to_free;
|
struct buffer_head *bh = buffers_to_free;
|
||||||
|
Loading…
Reference in New Issue
Block a user