lkml.org 
[lkml]   [2007]   [Apr]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4/5] NFS: Fix race in nfs_set_page_dirty
    Date
    From: Trond Myklebust <Trond.Myklebust@netapp.com>

    Protect nfs_set_page_dirty() against races with nfs_inode_add_request.

    Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
    ---

    fs/nfs/write.c | 17 ++++++++++++++---
    1 files changed, 14 insertions(+), 3 deletions(-)

    diff --git a/fs/nfs/write.c b/fs/nfs/write.c
    index ce5b4a9..7975589 100644
    --- a/fs/nfs/write.c
    +++ b/fs/nfs/write.c
    @@ -388,6 +388,8 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
    }
    SetPagePrivate(req->wb_page);
    set_page_private(req->wb_page, (unsigned long)req);
    + if (PageDirty(req->wb_page))
    + set_bit(PG_NEED_FLUSH, &req->wb_flags);
    nfsi->npages++;
    atomic_inc(&req->wb_count);
    return 0;
    @@ -407,6 +409,8 @@ static void nfs_inode_remove_request(struct nfs_page *req)
    set_page_private(req->wb_page, 0);
    ClearPagePrivate(req->wb_page);
    radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
    + if (test_and_clear_bit(PG_NEED_FLUSH, &req->wb_flags))
    + __set_page_dirty_nobuffers(req->wb_page);
    nfsi->npages--;
    if (!nfsi->npages) {
    spin_unlock(&nfsi->req_lock);
    @@ -1527,15 +1531,22 @@ int nfs_wb_page(struct inode *inode, struct page* page)

    int nfs_set_page_dirty(struct page *page)
    {
    + spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock;
    struct nfs_page *req;
    + int ret;

    - req = nfs_page_find_request(page);
    + spin_lock(req_lock);
    + req = nfs_page_find_request_locked(page);
    if (req != NULL) {
    /* Mark any existing write requests for flushing */
    - set_bit(PG_NEED_FLUSH, &req->wb_flags);
    + ret = !test_and_set_bit(PG_NEED_FLUSH, &req->wb_flags);
    + spin_unlock(req_lock);
    nfs_release_request(req);
    + return ret;
    }
    - return __set_page_dirty_nobuffers(page);
    + ret = __set_page_dirty_nobuffers(page);
    + spin_unlock(req_lock);
    + return ret;
    }


    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/
    \
     
     \ /
      Last update: 2007-04-20 22:37    [W:0.027 / U:92.388 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site