Commit 6967614761fd305b3414d9485d89dc2e0a407410

Authored by Mark Fasheh
Committed by Linus Torvalds
1 parent 54cb8821de

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

... ... @@ -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) {