aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c66
1 files changed, 33 insertions, 33 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 310fdeca6250..6df8319de060 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -155,6 +155,29 @@ void nfs_writedata_release(void *wdata)
155 nfs_writedata_free(wdata); 155 nfs_writedata_free(wdata);
156} 156}
157 157
158static struct nfs_page *nfs_page_find_request_locked(struct page *page)
159{
160 struct nfs_page *req = NULL;
161
162 if (PagePrivate(page)) {
163 req = (struct nfs_page *)page_private(page);
164 if (req != NULL)
165 atomic_inc(&req->wb_count);
166 }
167 return req;
168}
169
170static struct nfs_page *nfs_page_find_request(struct page *page)
171{
172 struct nfs_page *req = NULL;
173 spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock;
174
175 spin_lock(req_lock);
176 req = nfs_page_find_request_locked(page);
177 spin_unlock(req_lock);
178 return req;
179}
180
158/* Adjust the file length if we're writing beyond the end */ 181/* Adjust the file length if we're writing beyond the end */
159static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count) 182static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int count)
160{ 183{
@@ -429,6 +452,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
429 nfsi->change_attr++; 452 nfsi->change_attr++;
430 } 453 }
431 SetPagePrivate(req->wb_page); 454 SetPagePrivate(req->wb_page);
455 set_page_private(req->wb_page, (unsigned long)req);
432 nfsi->npages++; 456 nfsi->npages++;
433 atomic_inc(&req->wb_count); 457 atomic_inc(&req->wb_count);
434 return 0; 458 return 0;
@@ -445,6 +469,7 @@ static void nfs_inode_remove_request(struct nfs_page *req)
445 BUG_ON (!NFS_WBACK_BUSY(req)); 469 BUG_ON (!NFS_WBACK_BUSY(req));
446 470
447 spin_lock(&nfsi->req_lock); 471 spin_lock(&nfsi->req_lock);
472 set_page_private(req->wb_page, 0);
448 ClearPagePrivate(req->wb_page); 473 ClearPagePrivate(req->wb_page);
449 radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); 474 radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
450 nfsi->npages--; 475 nfsi->npages--;
@@ -459,33 +484,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
459} 484}
460 485
461/* 486/*
462 * Find a request
463 */
464static inline struct nfs_page *
465_nfs_find_request(struct inode *inode, unsigned long index)
466{
467 struct nfs_inode *nfsi = NFS_I(inode);
468 struct nfs_page *req;
469
470 req = (struct nfs_page*)radix_tree_lookup(&nfsi->nfs_page_tree, index);
471 if (req)
472 atomic_inc(&req->wb_count);
473 return req;
474}
475
476static struct nfs_page *
477nfs_find_request(struct inode *inode, unsigned long index)
478{
479 struct nfs_page *req;
480 struct nfs_inode *nfsi = NFS_I(inode);
481
482 spin_lock(&nfsi->req_lock);
483 req = _nfs_find_request(inode, index);
484 spin_unlock(&nfsi->req_lock);
485 return req;
486}
487
488/*
489 * Add a request to the inode's dirty list. 487 * Add a request to the inode's dirty list.
490 */ 488 */
491static void 489static void
@@ -699,10 +697,11 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
699 * A request for the page we wish to update 697 * A request for the page we wish to update
700 */ 698 */
701 spin_lock(&nfsi->req_lock); 699 spin_lock(&nfsi->req_lock);
702 req = _nfs_find_request(inode, page->index); 700 req = nfs_page_find_request_locked(page);
703 if (req) { 701 if (req) {
704 if (!nfs_lock_request_dontget(req)) { 702 if (!nfs_lock_request_dontget(req)) {
705 int error; 703 int error;
704
706 spin_unlock(&nfsi->req_lock); 705 spin_unlock(&nfsi->req_lock);
707 error = nfs_wait_on_request(req); 706 error = nfs_wait_on_request(req);
708 nfs_release_request(req); 707 nfs_release_request(req);
@@ -770,7 +769,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
770int nfs_flush_incompatible(struct file *file, struct page *page) 769int nfs_flush_incompatible(struct file *file, struct page *page)
771{ 770{
772 struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data; 771 struct nfs_open_context *ctx = (struct nfs_open_context *)file->private_data;
773 struct inode *inode = page->mapping->host;
774 struct nfs_page *req; 772 struct nfs_page *req;
775 int status = 0; 773 int status = 0;
776 /* 774 /*
@@ -781,11 +779,13 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
781 * Also do the same if we find a request from an existing 779 * Also do the same if we find a request from an existing
782 * dropped page. 780 * dropped page.
783 */ 781 */
784 req = nfs_find_request(inode, page->index); 782 req = nfs_page_find_request(page);
785 if (req) { 783 if (req != NULL) {
786 if (req->wb_page != page || ctx != req->wb_context) 784 int do_flush = req->wb_page != page || req->wb_context != ctx;
787 status = nfs_wb_page(inode, page); 785
788 nfs_release_request(req); 786 nfs_release_request(req);
787 if (do_flush)
788 status = nfs_wb_page(page->mapping->host, page);
789 } 789 }
790 return (status < 0) ? status : 0; 790 return (status < 0) ? status : 0;
791} 791}