diff mbox

[3.8.y.z,extended,stable] Patch "UBIFS: fix an mmap and fsync race condition" has been added to staging queue

Message ID 1405977688-32648-1-git-send-email-kamal@canonical.com
State New
Headers show

Commit Message

Kamal Mostafa July 21, 2014, 9:21 p.m. UTC
This is a note to let you know that I have just added a patch titled

    UBIFS: fix an mmap and fsync race condition

to the linux-3.8.y-queue branch of the 3.8.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.8.y-queue

This patch is scheduled to be released in version 3.8.13.27.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.8.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

------

From 2bad0e7b109665009e7b58ec8b9f9c30ba0fbdd0 Mon Sep 17 00:00:00 2001
From: hujianyang <hujianyang@huawei.com>
Date: Wed, 30 Apr 2014 14:06:06 +0800
Subject: UBIFS: fix an mmap and fsync race condition

commit 691a7c6f28ac90cccd0dbcf81348ea90b211bdd0 upstream.

There is a race condition in UBIFS:

Thread A (mmap)                        Thread B (fsync)

->__do_fault                           ->write_cache_pages
   -> ubifs_vm_page_mkwrite
       -> budget_space
       -> lock_page
       -> release/convert_page_budget
       -> SetPagePrivate
       -> TestSetPageDirty
       -> unlock_page
                                       -> lock_page
                                           -> TestClearPageDirty
                                           -> ubifs_writepage
                                               -> do_writepage
                                                   -> release_budget
                                                   -> ClearPagePrivate
                                                   -> unlock_page
   -> !(ret & VM_FAULT_LOCKED)
   -> lock_page
   -> set_page_dirty
       -> ubifs_set_page_dirty
           -> TestSetPageDirty (set page dirty without budgeting)
   -> unlock_page

This leads to situation where we have a diry page but no budget allocated for
this page, so further write-back may fail with -ENOSPC.

In this fix we return from page_mkwrite without performing unlock_page. We
return VM_FAULT_LOCKED instead. After doing this, the race above will not
happen.

Signed-off-by: hujianyang <hujianyang@huawei.com>
Tested-by: Laurence Withers <lwithers@guralp.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
---
 fs/ubifs/file.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--
1.9.1
diff mbox

Patch

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 5bc7781..bc7798d 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1522,8 +1522,7 @@  static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma,
 			ubifs_release_dirty_inode_budget(c, ui);
 	}

-	unlock_page(page);
-	return 0;
+	return VM_FAULT_LOCKED;

 out_unlock:
 	unlock_page(page);