lkml.org 
[lkml]   [2011]   [May]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH v3 2/3] ext4: Wait for writeback to complete while making pages writable
    In order to stabilize pages during disk writes, ext4_page_mkwrite must wait for
    writeback operations to complete before making a page writable. Furthermore,
    the function must return locked pages, and recheck the writeback status if the
    page lock is ever dropped.

    Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
    ---

    fs/ext4/inode.c | 24 +++++++++++++++++++-----
    1 files changed, 19 insertions(+), 5 deletions(-)

    diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
    index 3db34b2..1d162a2 100644
    --- a/fs/ext4/inode.c
    +++ b/fs/ext4/inode.c
    @@ -5809,15 +5809,19 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
    goto out_unlock;
    }
    ret = 0;
    - if (PageMappedToDisk(page))
    - goto out_unlock;
    +
    + lock_page(page);
    + wait_on_page_writeback(page);
    + if (PageMappedToDisk(page)) {
    + up_read(&inode->i_alloc_sem);
    + return VM_FAULT_LOCKED;
    + }

    if (page->index == size >> PAGE_CACHE_SHIFT)
    len = size & ~PAGE_CACHE_MASK;
    else
    len = PAGE_CACHE_SIZE;

    - lock_page(page);
    /*
    * return if we have all the buffers mapped. This avoid
    * the need to call write_begin/write_end which does a
    @@ -5827,8 +5831,8 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
    if (page_has_buffers(page)) {
    if (!walk_page_buffers(NULL, page_buffers(page), 0, len, NULL,
    ext4_bh_unmapped)) {
    - unlock_page(page);
    - goto out_unlock;
    + up_read(&inode->i_alloc_sem);
    + return VM_FAULT_LOCKED;
    }
    }
    unlock_page(page);
    @@ -5848,6 +5852,16 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
    if (ret < 0)
    goto out_unlock;
    ret = 0;
    +
    + /*
    + * write_begin/end might have created a dirty page and someone
    + * could wander in and start the IO. Make sure that hasn't
    + * happened.
    + */
    + lock_page(page);
    + wait_on_page_writeback(page);
    + up_read(&inode->i_alloc_sem);
    + return VM_FAULT_LOCKED;
    out_unlock:
    if (ret)
    ret = VM_FAULT_SIGBUS;

    \
     
     \ /
      Last update: 2011-05-04 19:43    [W:0.022 / U:95.632 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site