Commit 6967614761fd305b3414d9485d89dc2e0a407410
Committed by
Linus Torvalds
1 parent
54cb8821de
Exists in
master
and in
4 other branches
ocfs2: release page lock before calling ->page_mkwrite
__do_fault() was calling ->page_mkwrite() with the page lock held, which violates the locking rules for that callback. Release and retake the page lock around the callback to avoid deadlocking file systems which manually take it. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 9 additions and 5 deletions Side-by-side Diff
mm/memory.c
... | ... | @@ -2369,11 +2369,14 @@ |
2369 | 2369 | * address space wants to know that the page is about |
2370 | 2370 | * to become writable |
2371 | 2371 | */ |
2372 | - if (vma->vm_ops->page_mkwrite && | |
2373 | - vma->vm_ops->page_mkwrite(vma, page) < 0) { | |
2374 | - fdata.type = VM_FAULT_SIGBUS; | |
2375 | - anon = 1; /* no anon but release faulted_page */ | |
2376 | - goto out; | |
2372 | + if (vma->vm_ops->page_mkwrite) { | |
2373 | + unlock_page(page); | |
2374 | + if (vma->vm_ops->page_mkwrite(vma, page) < 0) { | |
2375 | + fdata.type = VM_FAULT_SIGBUS; | |
2376 | + anon = 1; /* no anon but release faulted_page */ | |
2377 | + goto out_unlocked; | |
2378 | + } | |
2379 | + lock_page(page); | |
2377 | 2380 | } |
2378 | 2381 | } |
2379 | 2382 | |
... | ... | @@ -2425,6 +2428,7 @@ |
2425 | 2428 | |
2426 | 2429 | out: |
2427 | 2430 | unlock_page(faulted_page); |
2431 | +out_unlocked: | |
2428 | 2432 | if (anon) |
2429 | 2433 | page_cache_release(faulted_page); |
2430 | 2434 | else if (dirty_page) { |