From: Trond Myklebust Date: Tue, 5 Dec 2006 05:35:35 +0000 (-0500) Subject: NFS: Store pointer to the nfs_page in page->private X-Git-Tag: v2.6.20-rc1~34^2~412^2~46 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=277459d2e2cd40594967757e8fd016c4c7016614;p=linux-2.6 NFS: Store pointer to the nfs_page in page->private This will allow fast lookup of the nfs_page from the struct page instead of having to search the radix tree. Signed-off-by: Trond Myklebust --- diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 310fdeca62..6df8319de0 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -155,6 +155,29 @@ void nfs_writedata_release(void *wdata) nfs_writedata_free(wdata); } +static struct nfs_page *nfs_page_find_request_locked(struct page *page) +{ + struct nfs_page *req = NULL; + + if (PagePrivate(page)) { + req = (struct nfs_page *)page_private(page); + if (req != NULL) + atomic_inc(&req->wb_count); + } + return req; +} + +static struct nfs_page *nfs_page_find_request(struct page *page) +{ + struct nfs_page *req = NULL; + spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; + + spin_lock(req_lock); + req = nfs_page_find_request_locked(page); + spin_unlock(req_lock); + return req; +} + /* Adjust the file length if we're writing beyond the end */ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) { @@ -429,6 +452,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) nfsi->change_attr++; } SetPagePrivate(req->wb_page); + set_page_private(req->wb_page, (unsigned long)req); nfsi->npages++; atomic_inc(&req->wb_count); return 0; @@ -445,6 +469,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) BUG_ON (!NFS_WBACK_BUSY(req)); spin_lock(&nfsi->req_lock); + set_page_private(req->wb_page, 0); ClearPagePrivate(req->wb_page); radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); nfsi->npages--; @@ -458,33 +483,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) nfs_release_request(req); } -/* - * Find a request - */ -static inline struct nfs_page * -_nfs_find_request(struct inode *inode, unsigned long index) -{ - struct nfs_inode *nfsi = NFS_I(inode); - struct nfs_page *req; - - req = (struct nfs_page*)radix_tree_lookup(&nfsi->nfs_page_tree, index); - if (req) - atomic_inc(&req->wb_count); - return req; -} - -static struct nfs_page * -nfs_find_request(struct inode *inode, unsigned long index) -{ - struct nfs_page *req; - struct nfs_inode *nfsi = NFS_I(inode); - - spin_lock(&nfsi->req_lock); - req = _nfs_find_request(inode, index); - spin_unlock(&nfsi->req_lock); - return req; -} - /* * Add a request to the inode's dirty list. */ @@ -699,10 +697,11 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, * A request for the page we wish to update */ spin_lock(&nfsi->req_lock); - req = _nfs_find_request(inode, page->index); + req = nfs_page_find_request_locked(page); if (req) { if (!nfs_lock_request_dontget(req)) { int error; + spin_unlock(&nfsi->req_lock); error = nfs_wait_on_request(req); nfs_release_request(req); @@ -770,7 +769,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, int nfs_flush_incompatible(struct file *file, struct page *page) { struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; - struct inode *inode = page->mapping->host; struct nfs_page *req; int status = 0; /* @@ -781,11 +779,13 @@ int nfs_flush_incompatible(struct file *file, struct page *page) * Also do the same if we find a request from an existing * dropped page. */ - req = nfs_find_request(inode, page->index); - if (req) { - if (req->wb_page != page || ctx != req->wb_context) - status = nfs_wb_page(inode, page); + req = nfs_page_find_request(page); + if (req != NULL) { + int do_flush = req->wb_page != page || req->wb_context != ctx; + nfs_release_request(req); + if (do_flush) + status = nfs_wb_page(page->mapping->host, page); } return (status < 0) ? status : 0; }