diff options
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 9347ab7c9574..c483cc50b82e 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -126,12 +126,16 @@ void nfs_writedata_release(struct nfs_write_data *wdata) | |||
126 | put_nfs_open_context(wdata->args.context); | 126 | put_nfs_open_context(wdata->args.context); |
127 | if (wdata->pages.pagevec != wdata->pages.page_array) | 127 | if (wdata->pages.pagevec != wdata->pages.page_array) |
128 | kfree(wdata->pages.pagevec); | 128 | kfree(wdata->pages.pagevec); |
129 | if (wdata != &write_header->rpc_data) | 129 | if (wdata == &write_header->rpc_data) { |
130 | kfree(wdata); | ||
131 | else | ||
132 | wdata->header = NULL; | 130 | wdata->header = NULL; |
131 | wdata = NULL; | ||
132 | } | ||
133 | if (atomic_dec_and_test(&hdr->refcnt)) | 133 | if (atomic_dec_and_test(&hdr->refcnt)) |
134 | hdr->completion_ops->completion(hdr); | 134 | hdr->completion_ops->completion(hdr); |
135 | /* Note: we only free the rpc_task after callbacks are done. | ||
136 | * See the comment in rpc_free_task() for why | ||
137 | */ | ||
138 | kfree(wdata); | ||
135 | } | 139 | } |
136 | EXPORT_SYMBOL_GPL(nfs_writedata_release); | 140 | EXPORT_SYMBOL_GPL(nfs_writedata_release); |
137 | 141 | ||
@@ -202,7 +206,6 @@ out: | |||
202 | /* A writeback failed: mark the page as bad, and invalidate the page cache */ | 206 | /* A writeback failed: mark the page as bad, and invalidate the page cache */ |
203 | static void nfs_set_pageerror(struct page *page) | 207 | static void nfs_set_pageerror(struct page *page) |
204 | { | 208 | { |
205 | SetPageError(page); | ||
206 | nfs_zap_mapping(page_file_mapping(page)->host, page_file_mapping(page)); | 209 | nfs_zap_mapping(page_file_mapping(page)->host, page_file_mapping(page)); |
207 | } | 210 | } |
208 | 211 | ||
@@ -239,21 +242,18 @@ int nfs_congestion_kb; | |||
239 | #define NFS_CONGESTION_OFF_THRESH \ | 242 | #define NFS_CONGESTION_OFF_THRESH \ |
240 | (NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2)) | 243 | (NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2)) |
241 | 244 | ||
242 | static int nfs_set_page_writeback(struct page *page) | 245 | static void nfs_set_page_writeback(struct page *page) |
243 | { | 246 | { |
247 | struct nfs_server *nfss = NFS_SERVER(page_file_mapping(page)->host); | ||
244 | int ret = test_set_page_writeback(page); | 248 | int ret = test_set_page_writeback(page); |
245 | 249 | ||
246 | if (!ret) { | 250 | WARN_ON_ONCE(ret != 0); |
247 | struct inode *inode = page_file_mapping(page)->host; | ||
248 | struct nfs_server *nfss = NFS_SERVER(inode); | ||
249 | 251 | ||
250 | if (atomic_long_inc_return(&nfss->writeback) > | 252 | if (atomic_long_inc_return(&nfss->writeback) > |
251 | NFS_CONGESTION_ON_THRESH) { | 253 | NFS_CONGESTION_ON_THRESH) { |
252 | set_bdi_congested(&nfss->backing_dev_info, | 254 | set_bdi_congested(&nfss->backing_dev_info, |
253 | BLK_RW_ASYNC); | 255 | BLK_RW_ASYNC); |
254 | } | ||
255 | } | 256 | } |
256 | return ret; | ||
257 | } | 257 | } |
258 | 258 | ||
259 | static void nfs_end_page_writeback(struct page *page) | 259 | static void nfs_end_page_writeback(struct page *page) |
@@ -315,10 +315,10 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, | |||
315 | if (IS_ERR(req)) | 315 | if (IS_ERR(req)) |
316 | goto out; | 316 | goto out; |
317 | 317 | ||
318 | ret = nfs_set_page_writeback(page); | 318 | nfs_set_page_writeback(page); |
319 | BUG_ON(ret != 0); | 319 | WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags)); |
320 | BUG_ON(test_bit(PG_CLEAN, &req->wb_flags)); | ||
321 | 320 | ||
321 | ret = 0; | ||
322 | if (!nfs_pageio_add_request(pgio, req)) { | 322 | if (!nfs_pageio_add_request(pgio, req)) { |
323 | nfs_redirty_request(req); | 323 | nfs_redirty_request(req); |
324 | ret = pgio->pg_error; | 324 | ret = pgio->pg_error; |
@@ -451,8 +451,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
451 | struct inode *inode = req->wb_context->dentry->d_inode; | 451 | struct inode *inode = req->wb_context->dentry->d_inode; |
452 | struct nfs_inode *nfsi = NFS_I(inode); | 452 | struct nfs_inode *nfsi = NFS_I(inode); |
453 | 453 | ||
454 | BUG_ON (!NFS_WBACK_BUSY(req)); | ||
455 | |||
456 | spin_lock(&inode->i_lock); | 454 | spin_lock(&inode->i_lock); |
457 | if (likely(!PageSwapCache(req->wb_page))) { | 455 | if (likely(!PageSwapCache(req->wb_page))) { |
458 | set_page_private(req->wb_page, 0); | 456 | set_page_private(req->wb_page, 0); |
@@ -884,7 +882,7 @@ static bool nfs_write_pageuptodate(struct page *page, struct inode *inode) | |||
884 | { | 882 | { |
885 | if (nfs_have_delegated_attributes(inode)) | 883 | if (nfs_have_delegated_attributes(inode)) |
886 | goto out; | 884 | goto out; |
887 | if (NFS_I(inode)->cache_validity & NFS_INO_REVAL_PAGECACHE) | 885 | if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_DATA|NFS_INO_REVAL_PAGECACHE)) |
888 | return false; | 886 | return false; |
889 | out: | 887 | out: |
890 | return PageUptodate(page) != 0; | 888 | return PageUptodate(page) != 0; |
@@ -1727,7 +1725,6 @@ int nfs_wb_page_cancel(struct inode *inode, struct page *page) | |||
1727 | struct nfs_page *req; | 1725 | struct nfs_page *req; |
1728 | int ret = 0; | 1726 | int ret = 0; |
1729 | 1727 | ||
1730 | BUG_ON(!PageLocked(page)); | ||
1731 | for (;;) { | 1728 | for (;;) { |
1732 | wait_on_page_writeback(page); | 1729 | wait_on_page_writeback(page); |
1733 | req = nfs_page_find_request(page); | 1730 | req = nfs_page_find_request(page); |
@@ -1801,7 +1798,8 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage, | |||
1801 | if (PagePrivate(page)) | 1798 | if (PagePrivate(page)) |
1802 | return -EBUSY; | 1799 | return -EBUSY; |
1803 | 1800 | ||
1804 | nfs_fscache_release_page(page, GFP_KERNEL); | 1801 | if (!nfs_fscache_release_page(page, GFP_KERNEL)) |
1802 | return -EBUSY; | ||
1805 | 1803 | ||
1806 | return migrate_page(mapping, newpage, page, mode); | 1804 | return migrate_page(mapping, newpage, page, mode); |
1807 | } | 1805 | } |
@@ -1829,7 +1827,7 @@ int __init nfs_init_writepagecache(void) | |||
1829 | goto out_destroy_write_mempool; | 1827 | goto out_destroy_write_mempool; |
1830 | 1828 | ||
1831 | nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, | 1829 | nfs_commit_mempool = mempool_create_slab_pool(MIN_POOL_COMMIT, |
1832 | nfs_wdata_cachep); | 1830 | nfs_cdata_cachep); |
1833 | if (nfs_commit_mempool == NULL) | 1831 | if (nfs_commit_mempool == NULL) |
1834 | goto out_destroy_commit_cache; | 1832 | goto out_destroy_commit_cache; |
1835 | 1833 | ||