summaryrefslogtreecommitdiff
path: root/mm
diff options
context:
space:
mode:
authorMingming Cao <cmm@us.ibm.com>2008-07-25 01:46:22 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2008-08-06 10:10:58 -0700
commit53f501a19fc08631458f228b5ad2bdc46d65846b (patch)
treedf15493bd00a8895bfa5dead687feb703459caf9 /mm
parentabc527c920d94205e1ffefaf2e5cbd0c4ea98c8f (diff)
jbd: fix race between free buffer and commit transaction
commit 3f31fddfa26b7594b44ff2b34f9a04ba409e0f91 upstream journal_try_to_free_buffers() could race with jbd commit transaction when the later is holding the buffer reference while waiting for the data buffer to flush to disk. If the caller of journal_try_to_free_buffers() request tries hard to release the buffers, it will treat the failure as error and return back to the caller. We have seen the directo IO failed due to this race. Some of the caller of releasepage() also expecting the buffer to be dropped when passed with GFP_KERNEL mask to the releasepage()->journal_try_to_free_buffers(). With this patch, if the caller is passing the __GFP_WAIT and __GFP_FS to indicating this call could wait, in case of try_to_free_buffers() failed, let's waiting for journal_commit_transaction() to finish commit the current committing transaction, then try to free those buffers again. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Mingming Cao <cmm@us.ibm.com> Reviewed-by: Badari Pulavarty <pbadari@us.ibm.com> Acked-by: Jan Kara <jack@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'mm')
-rw-r--r--mm/filemap.c3
1 files changed, 1 insertions, 2 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index 703f2c8a56a8..d721ad537e7f 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2574,9 +2574,8 @@ out:
* Otherwise return zero.
*
* The @gfp_mask argument specifies whether I/O may be performed to release
- * this page (__GFP_IO), and whether the call may block (__GFP_WAIT).
+ * this page (__GFP_IO), and whether the call may block (__GFP_WAIT & __GFP_FS).
*
- * NOTE: @gfp_mask may go away, and this function may become non-blocking.
*/
int try_to_release_page(struct page *page, gfp_t gfp_mask)
{