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>
This commit is contained in:
parent
54cb8821de
commit
6967614761
1 changed files with 9 additions and 5 deletions
14
mm/memory.c
14
mm/memory.c
|
@ -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
|
* address space wants to know that the page is about
|
||||||
* to become writable
|
* to become writable
|
||||||
*/
|
*/
|
||||||
if (vma->vm_ops->page_mkwrite &&
|
if (vma->vm_ops->page_mkwrite) {
|
||||||
vma->vm_ops->page_mkwrite(vma, page) < 0) {
|
unlock_page(page);
|
||||||
fdata.type = VM_FAULT_SIGBUS;
|
if (vma->vm_ops->page_mkwrite(vma, page) < 0) {
|
||||||
anon = 1; /* no anon but release faulted_page */
|
fdata.type = VM_FAULT_SIGBUS;
|
||||||
goto out;
|
anon = 1; /* no anon but release faulted_page */
|
||||||
|
goto out_unlocked;
|
||||||
|
}
|
||||||
|
lock_page(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2425,6 +2428,7 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
unlock_page(faulted_page);
|
unlock_page(faulted_page);
|
||||||
|
out_unlocked:
|
||||||
if (anon)
|
if (anon)
|
||||||
page_cache_release(faulted_page);
|
page_cache_release(faulted_page);
|
||||||
else if (dirty_page) {
|
else if (dirty_page) {
|
||||||
|
|
Loading…
Reference in a new issue