From 6967614761fd305b3414d9485d89dc2e0a407410 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Thu, 19 Jul 2007 01:47:00 -0700 Subject: 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 Cc: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/memory.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'mm/memory.c') diff --git a/mm/memory.c b/mm/memory.c index eee7fec3ab5..7abd3899848 100644 --- a/mm/memory.c +++ b/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 * 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); } } @@ -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) { -- cgit v1.2.3-70-g09d2