Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=acee478afc6ff7e1b8852d9a4dca1ff36021414d
Commit:     acee478afc6ff7e1b8852d9a4dca1ff36021414d
Parent:     8b1f9ee56e21e505a3d5d3e33f823006d1abdbaf
Author:     Trond Myklebust <[EMAIL PROTECTED]>
AuthorDate: Tue Jan 22 17:13:07 2008 -0500
Committer:  Trond Myklebust <[EMAIL PROTECTED]>
CommitDate: Wed Jan 30 02:05:24 2008 -0500

    NFS: Clean up the write request locking.
    
    Ensure that we set/clear NFS_PAGE_TAG_LOCKED when the nfs_page is hashed.
    
    Signed-off-by: Trond Myklebust <[EMAIL PROTECTED]>
---
 fs/nfs/pagelist.c        |   13 ++++++++-----
 fs/nfs/write.c           |   16 +++++++---------
 include/linux/nfs_page.h |   13 +------------
 3 files changed, 16 insertions(+), 26 deletions(-)

diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 345bb9b..3b3dbb9 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -111,13 +111,14 @@ void nfs_unlock_request(struct nfs_page *req)
  * nfs_set_page_tag_locked - Tag a request as locked
  * @req:
  */
-static int nfs_set_page_tag_locked(struct nfs_page *req)
+int nfs_set_page_tag_locked(struct nfs_page *req)
 {
        struct nfs_inode *nfsi = NFS_I(req->wb_context->path.dentry->d_inode);
 
-       if (!nfs_lock_request(req))
+       if (!nfs_lock_request_dontget(req))
                return 0;
-       radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, 
NFS_PAGE_TAG_LOCKED);
+       if (req->wb_page != NULL)
+               radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, 
NFS_PAGE_TAG_LOCKED);
        return 1;
 }
 
@@ -132,9 +133,10 @@ void nfs_clear_page_tag_locked(struct nfs_page *req)
        if (req->wb_page != NULL) {
                spin_lock(&inode->i_lock);
                radix_tree_tag_clear(&nfsi->nfs_page_tree, req->wb_index, 
NFS_PAGE_TAG_LOCKED);
+               nfs_unlock_request(req);
                spin_unlock(&inode->i_lock);
-       }
-       nfs_unlock_request(req);
+       } else
+               nfs_unlock_request(req);
 }
 
 /**
@@ -421,6 +423,7 @@ int nfs_scan_list(struct nfs_inode *nfsi,
                                goto out;
                        idx_start = req->wb_index + 1;
                        if (nfs_set_page_tag_locked(req)) {
+                               kref_get(&req->wb_kref);
                                nfs_list_remove_request(req);
                                radix_tree_tag_clear(&nfsi->nfs_page_tree,
                                                req->wb_index, tag);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 51cc1bd..092e79c 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -196,7 +196,7 @@ static int nfs_writepage_setup(struct nfs_open_context 
*ctx, struct page *page,
        }
        /* Update file length */
        nfs_grow_file(page, offset, count);
-       nfs_unlock_request(req);
+       nfs_clear_page_tag_locked(req);
        return 0;
 }
 
@@ -252,7 +252,6 @@ static int nfs_page_async_flush(struct 
nfs_pageio_descriptor *pgio,
                                struct page *page)
 {
        struct inode *inode = page->mapping->host;
-       struct nfs_inode *nfsi = NFS_I(inode);
        struct nfs_page *req;
        int ret;
 
@@ -263,10 +262,10 @@ static int nfs_page_async_flush(struct 
nfs_pageio_descriptor *pgio,
                        spin_unlock(&inode->i_lock);
                        return 0;
                }
-               if (nfs_lock_request_dontget(req))
+               if (nfs_set_page_tag_locked(req))
                        break;
                /* Note: If we hold the page lock, as is the case in 
nfs_writepage,
-                *       then the call to nfs_lock_request_dontget() will always
+                *       then the call to nfs_set_page_tag_locked() will always
                 *       succeed provided that someone hasn't already marked the
                 *       request as dirty (in which case we don't care).
                 */
@@ -280,7 +279,7 @@ static int nfs_page_async_flush(struct 
nfs_pageio_descriptor *pgio,
        if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
                /* This request is marked for commit */
                spin_unlock(&inode->i_lock);
-               nfs_unlock_request(req);
+               nfs_clear_page_tag_locked(req);
                nfs_pageio_complete(pgio);
                return 0;
        }
@@ -288,8 +287,6 @@ static int nfs_page_async_flush(struct 
nfs_pageio_descriptor *pgio,
                spin_unlock(&inode->i_lock);
                BUG();
        }
-       radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index,
-                       NFS_PAGE_TAG_LOCKED);
        spin_unlock(&inode->i_lock);
        nfs_pageio_add_request(pgio, req);
        return 0;
@@ -381,6 +378,7 @@ static int nfs_inode_add_request(struct inode *inode, 
struct nfs_page *req)
        set_page_private(req->wb_page, (unsigned long)req);
        nfsi->npages++;
        kref_get(&req->wb_kref);
+       radix_tree_tag_set(&nfsi->nfs_page_tree, req->wb_index, 
NFS_PAGE_TAG_LOCKED);
        return 0;
 }
 
@@ -596,7 +594,7 @@ static struct nfs_page * nfs_update_request(struct 
nfs_open_context* ctx,
                spin_lock(&inode->i_lock);
                req = nfs_page_find_request_locked(page);
                if (req) {
-                       if (!nfs_lock_request_dontget(req)) {
+                       if (!nfs_set_page_tag_locked(req)) {
                                int error;
 
                                spin_unlock(&inode->i_lock);
@@ -646,7 +644,7 @@ static struct nfs_page * nfs_update_request(struct 
nfs_open_context* ctx,
            || req->wb_page != page
            || !nfs_dirty_request(req)
            || offset > rqend || end < req->wb_offset) {
-               nfs_unlock_request(req);
+               nfs_clear_page_tag_locked(req);
                return ERR_PTR(-EBUSY);
        }
 
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 30dbcc1..a1676e1 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -83,6 +83,7 @@ extern        void nfs_pageio_complete(struct 
nfs_pageio_descriptor *desc);
 extern void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *, pgoff_t);
 extern  int nfs_wait_on_request(struct nfs_page *);
 extern void nfs_unlock_request(struct nfs_page *req);
+extern int nfs_set_page_tag_locked(struct nfs_page *req);
 extern  void nfs_clear_page_tag_locked(struct nfs_page *req);
 
 
@@ -95,18 +96,6 @@ nfs_lock_request_dontget(struct nfs_page *req)
        return !test_and_set_bit(PG_BUSY, &req->wb_flags);
 }
 
-/*
- * Lock the page of an asynchronous request and take a reference
- */
-static inline int
-nfs_lock_request(struct nfs_page *req)
-{
-       if (test_and_set_bit(PG_BUSY, &req->wb_flags))
-               return 0;
-       kref_get(&req->wb_kref);
-       return 1;
-}
-
 /**
  * nfs_list_add_request - Insert a request into a list
  * @req: request
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to