Skip to content

Commit

Permalink
ocfs2: release page lock before calling ->page_mkwrite
Browse files Browse the repository at this point in the history
__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>
  • Loading branch information
Mark Fasheh authored and Linus Torvalds committed Jul 19, 2007
1 parent 54cb882 commit 6967614
Showing 1 changed file with 9 additions and 5 deletions.
14 changes: 9 additions & 5 deletions mm/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -2369,11 +2369,14 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
* address space wants to know that the page is about
* to become writable
*/
if (vma->vm_ops->page_mkwrite &&
vma->vm_ops->page_mkwrite(vma, page) < 0) {
fdata.type = VM_FAULT_SIGBUS;
anon = 1; /* no anon but release faulted_page */
goto out;
if (vma->vm_ops->page_mkwrite) {
unlock_page(page);
if (vma->vm_ops->page_mkwrite(vma, page) < 0) {
fdata.type = VM_FAULT_SIGBUS;
anon = 1; /* no anon but release faulted_page */
goto out_unlocked;
}
lock_page(page);
}
}

Expand Down Expand Up @@ -2425,6 +2428,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,

out:
unlock_page(faulted_page);
out_unlocked:
if (anon)
page_cache_release(faulted_page);
else if (dirty_page) {
Expand Down

0 comments on commit 6967614

Please sign in to comment.