aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/nfs/direct.c11
-rw-r--r--fs/nfs/inode.c9
-rw-r--r--fs/nfs/super.c4
-rw-r--r--fs/nfs/sysctl.c8
-rw-r--r--fs/nfs/write.c301
6 files changed, 213 insertions, 123 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 92d8ec859e22..cd3469720cbf 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1684,7 +1684,8 @@ go_ahead:
1684 * ... prune child dentries and writebacks if needed. 1684 * ... prune child dentries and writebacks if needed.
1685 */ 1685 */
1686 if (atomic_read(&old_dentry->d_count) > 1) { 1686 if (atomic_read(&old_dentry->d_count) > 1) {
1687 nfs_wb_all(old_inode); 1687 if (S_ISREG(old_inode->i_mode))
1688 nfs_wb_all(old_inode);
1688 shrink_dcache_parent(old_dentry); 1689 shrink_dcache_parent(old_dentry);
1689 } 1690 }
1690 nfs_inode_return_delegation(old_inode); 1691 nfs_inode_return_delegation(old_inode);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index b1c98ea39b72..2877744cb606 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -432,10 +432,10 @@ static void nfs_direct_commit_result(struct rpc_task *task, void *calldata)
432 if (NFS_PROTO(data->inode)->commit_done(task, data) != 0) 432 if (NFS_PROTO(data->inode)->commit_done(task, data) != 0)
433 return; 433 return;
434 if (unlikely(task->tk_status < 0)) { 434 if (unlikely(task->tk_status < 0)) {
435 dreq->error = task->tk_status; 435 dprintk("NFS: %5u commit failed with error %d.\n",
436 task->tk_pid, task->tk_status);
436 dreq->flags = NFS_ODIRECT_RESCHED_WRITES; 437 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
437 } 438 } else if (memcmp(&dreq->verf, &data->verf, sizeof(data->verf))) {
438 if (memcmp(&dreq->verf, &data->verf, sizeof(data->verf))) {
439 dprintk("NFS: %5u commit verify failed\n", task->tk_pid); 439 dprintk("NFS: %5u commit verify failed\n", task->tk_pid);
440 dreq->flags = NFS_ODIRECT_RESCHED_WRITES; 440 dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
441 } 441 }
@@ -531,9 +531,12 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
531 531
532 spin_lock(&dreq->lock); 532 spin_lock(&dreq->lock);
533 533
534 if (unlikely(dreq->error != 0))
535 goto out_unlock;
534 if (unlikely(status < 0)) { 536 if (unlikely(status < 0)) {
537 /* An error has occured, so we should not commit */
538 dreq->flags = 0;
535 dreq->error = status; 539 dreq->error = status;
536 goto out_unlock;
537 } 540 }
538 541
539 dreq->count += data->res.count; 542 dreq->count += data->res.count;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index af53c02f473b..44aa9b726573 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -341,8 +341,10 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
341 lock_kernel(); 341 lock_kernel();
342 nfs_begin_data_update(inode); 342 nfs_begin_data_update(inode);
343 /* Write all dirty data */ 343 /* Write all dirty data */
344 filemap_write_and_wait(inode->i_mapping); 344 if (S_ISREG(inode->i_mode)) {
345 nfs_wb_all(inode); 345 filemap_write_and_wait(inode->i_mapping);
346 nfs_wb_all(inode);
347 }
346 /* 348 /*
347 * Return any delegations if we're going to change ACLs 349 * Return any delegations if we're going to change ACLs
348 */ 350 */
@@ -429,7 +431,8 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
429 int err; 431 int err;
430 432
431 /* Flush out writes to the server in order to update c/mtime */ 433 /* Flush out writes to the server in order to update c/mtime */
432 nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT); 434 if (S_ISREG(inode->i_mode))
435 nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT);
433 436
434 /* 437 /*
435 * We may force a getattr if the user cares about atime. 438 * We may force a getattr if the user cares about atime.
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index bb516a2cfbaf..f1eae44b9a1a 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -151,10 +151,10 @@ int __init register_nfs_fs(void)
151 if (ret < 0) 151 if (ret < 0)
152 goto error_0; 152 goto error_0;
153 153
154#ifdef CONFIG_NFS_V4
155 ret = nfs_register_sysctl(); 154 ret = nfs_register_sysctl();
156 if (ret < 0) 155 if (ret < 0)
157 goto error_1; 156 goto error_1;
157#ifdef CONFIG_NFS_V4
158 ret = register_filesystem(&nfs4_fs_type); 158 ret = register_filesystem(&nfs4_fs_type);
159 if (ret < 0) 159 if (ret < 0)
160 goto error_2; 160 goto error_2;
@@ -165,9 +165,9 @@ int __init register_nfs_fs(void)
165#ifdef CONFIG_NFS_V4 165#ifdef CONFIG_NFS_V4
166error_2: 166error_2:
167 nfs_unregister_sysctl(); 167 nfs_unregister_sysctl();
168#endif
168error_1: 169error_1:
169 unregister_filesystem(&nfs_fs_type); 170 unregister_filesystem(&nfs_fs_type);
170#endif
171error_0: 171error_0:
172 return ret; 172 return ret;
173} 173}
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c
index fcdcafbb3293..b62481dabae9 100644
--- a/fs/nfs/sysctl.c
+++ b/fs/nfs/sysctl.c
@@ -50,6 +50,14 @@ static ctl_table nfs_cb_sysctls[] = {
50 .proc_handler = &proc_dointvec_jiffies, 50 .proc_handler = &proc_dointvec_jiffies,
51 .strategy = &sysctl_jiffies, 51 .strategy = &sysctl_jiffies,
52 }, 52 },
53 {
54 .ctl_name = CTL_UNNUMBERED,
55 .procname = "nfs_congestion_kb",
56 .data = &nfs_congestion_kb,
57 .maxlen = sizeof(nfs_congestion_kb),
58 .mode = 0644,
59 .proc_handler = &proc_dointvec,
60 },
53 { .ctl_name = 0 } 61 { .ctl_name = 0 }
54}; 62};
55 63
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index febdade91670..797558941745 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -12,6 +12,7 @@
12#include <linux/pagemap.h> 12#include <linux/pagemap.h>
13#include <linux/file.h> 13#include <linux/file.h>
14#include <linux/writeback.h> 14#include <linux/writeback.h>
15#include <linux/swap.h>
15 16
16#include <linux/sunrpc/clnt.h> 17#include <linux/sunrpc/clnt.h>
17#include <linux/nfs_fs.h> 18#include <linux/nfs_fs.h>
@@ -37,8 +38,6 @@
37static struct nfs_page * nfs_update_request(struct nfs_open_context*, 38static struct nfs_page * nfs_update_request(struct nfs_open_context*,
38 struct page *, 39 struct page *,
39 unsigned int, unsigned int); 40 unsigned int, unsigned int);
40static void nfs_mark_request_dirty(struct nfs_page *req);
41static int nfs_wait_on_write_congestion(struct address_space *, int);
42static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); 41static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how);
43static const struct rpc_call_ops nfs_write_partial_ops; 42static const struct rpc_call_ops nfs_write_partial_ops;
44static const struct rpc_call_ops nfs_write_full_ops; 43static const struct rpc_call_ops nfs_write_full_ops;
@@ -48,8 +47,6 @@ static struct kmem_cache *nfs_wdata_cachep;
48static mempool_t *nfs_wdata_mempool; 47static mempool_t *nfs_wdata_mempool;
49static mempool_t *nfs_commit_mempool; 48static mempool_t *nfs_commit_mempool;
50 49
51static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion);
52
53struct nfs_write_data *nfs_commit_alloc(void) 50struct nfs_write_data *nfs_commit_alloc(void)
54{ 51{
55 struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); 52 struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS);
@@ -211,6 +208,43 @@ static int wb_priority(struct writeback_control *wbc)
211} 208}
212 209
213/* 210/*
211 * NFS congestion control
212 */
213
214int nfs_congestion_kb;
215
216#define NFS_CONGESTION_ON_THRESH (nfs_congestion_kb >> (PAGE_SHIFT-10))
217#define NFS_CONGESTION_OFF_THRESH \
218 (NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2))
219
220static int nfs_set_page_writeback(struct page *page)
221{
222 int ret = test_set_page_writeback(page);
223
224 if (!ret) {
225 struct inode *inode = page->mapping->host;
226 struct nfs_server *nfss = NFS_SERVER(inode);
227
228 if (atomic_inc_return(&nfss->writeback) >
229 NFS_CONGESTION_ON_THRESH)
230 set_bdi_congested(&nfss->backing_dev_info, WRITE);
231 }
232 return ret;
233}
234
235static void nfs_end_page_writeback(struct page *page)
236{
237 struct inode *inode = page->mapping->host;
238 struct nfs_server *nfss = NFS_SERVER(inode);
239
240 end_page_writeback(page);
241 if (atomic_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) {
242 clear_bdi_congested(&nfss->backing_dev_info, WRITE);
243 congestion_end(WRITE);
244 }
245}
246
247/*
214 * Find an associated nfs write request, and prepare to flush it out 248 * Find an associated nfs write request, and prepare to flush it out
215 * Returns 1 if there was no write request, or if the request was 249 * Returns 1 if there was no write request, or if the request was
216 * already tagged by nfs_set_page_dirty.Returns 0 if the request 250 * already tagged by nfs_set_page_dirty.Returns 0 if the request
@@ -220,7 +254,8 @@ static int wb_priority(struct writeback_control *wbc)
220static int nfs_page_mark_flush(struct page *page) 254static int nfs_page_mark_flush(struct page *page)
221{ 255{
222 struct nfs_page *req; 256 struct nfs_page *req;
223 spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; 257 struct nfs_inode *nfsi = NFS_I(page->mapping->host);
258 spinlock_t *req_lock = &nfsi->req_lock;
224 int ret; 259 int ret;
225 260
226 spin_lock(req_lock); 261 spin_lock(req_lock);
@@ -244,11 +279,23 @@ static int nfs_page_mark_flush(struct page *page)
244 return ret; 279 return ret;
245 spin_lock(req_lock); 280 spin_lock(req_lock);
246 } 281 }
247 spin_unlock(req_lock); 282 if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
248 if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) { 283 /* This request is marked for commit */
249 nfs_mark_request_dirty(req); 284 spin_unlock(req_lock);
250 set_page_writeback(page); 285 nfs_unlock_request(req);
286 return 1;
251 } 287 }
288 if (nfs_set_page_writeback(page) == 0) {
289 nfs_list_remove_request(req);
290 /* add the request to the inode's dirty list. */
291 radix_tree_tag_set(&nfsi->nfs_page_tree,
292 req->wb_index, NFS_PAGE_TAG_DIRTY);
293 nfs_list_add_request(req, &nfsi->dirty);
294 nfsi->ndirty++;
295 spin_unlock(req_lock);
296 __mark_inode_dirty(page->mapping->host, I_DIRTY_PAGES);
297 } else
298 spin_unlock(req_lock);
252 ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); 299 ret = test_bit(PG_NEED_FLUSH, &req->wb_flags);
253 nfs_unlock_request(req); 300 nfs_unlock_request(req);
254 return ret; 301 return ret;
@@ -302,13 +349,8 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
302 return err; 349 return err;
303} 350}
304 351
305/*
306 * Note: causes nfs_update_request() to block on the assumption
307 * that the writeback is generated due to memory pressure.
308 */
309int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) 352int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
310{ 353{
311 struct backing_dev_info *bdi = mapping->backing_dev_info;
312 struct inode *inode = mapping->host; 354 struct inode *inode = mapping->host;
313 int err; 355 int err;
314 356
@@ -317,20 +359,12 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
317 err = generic_writepages(mapping, wbc); 359 err = generic_writepages(mapping, wbc);
318 if (err) 360 if (err)
319 return err; 361 return err;
320 while (test_and_set_bit(BDI_write_congested, &bdi->state) != 0) {
321 if (wbc->nonblocking)
322 return 0;
323 nfs_wait_on_write_congestion(mapping, 0);
324 }
325 err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc)); 362 err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc));
326 if (err < 0) 363 if (err < 0)
327 goto out; 364 goto out;
328 nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); 365 nfs_add_stats(inode, NFSIOS_WRITEPAGES, err);
329 err = 0; 366 err = 0;
330out: 367out:
331 clear_bit(BDI_write_congested, &bdi->state);
332 wake_up_all(&nfs_write_congestion);
333 congestion_end(WRITE);
334 return err; 368 return err;
335} 369}
336 370
@@ -354,13 +388,15 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
354 } 388 }
355 SetPagePrivate(req->wb_page); 389 SetPagePrivate(req->wb_page);
356 set_page_private(req->wb_page, (unsigned long)req); 390 set_page_private(req->wb_page, (unsigned long)req);
391 if (PageDirty(req->wb_page))
392 set_bit(PG_NEED_FLUSH, &req->wb_flags);
357 nfsi->npages++; 393 nfsi->npages++;
358 atomic_inc(&req->wb_count); 394 atomic_inc(&req->wb_count);
359 return 0; 395 return 0;
360} 396}
361 397
362/* 398/*
363 * Insert a write request into an inode 399 * Remove a write request from an inode
364 */ 400 */
365static void nfs_inode_remove_request(struct nfs_page *req) 401static void nfs_inode_remove_request(struct nfs_page *req)
366{ 402{
@@ -373,6 +409,8 @@ static void nfs_inode_remove_request(struct nfs_page *req)
373 set_page_private(req->wb_page, 0); 409 set_page_private(req->wb_page, 0);
374 ClearPagePrivate(req->wb_page); 410 ClearPagePrivate(req->wb_page);
375 radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); 411 radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
412 if (test_and_clear_bit(PG_NEED_FLUSH, &req->wb_flags))
413 __set_page_dirty_nobuffers(req->wb_page);
376 nfsi->npages--; 414 nfsi->npages--;
377 if (!nfsi->npages) { 415 if (!nfsi->npages) {
378 spin_unlock(&nfsi->req_lock); 416 spin_unlock(&nfsi->req_lock);
@@ -384,28 +422,9 @@ static void nfs_inode_remove_request(struct nfs_page *req)
384 nfs_release_request(req); 422 nfs_release_request(req);
385} 423}
386 424
387/*
388 * Add a request to the inode's dirty list.
389 */
390static void
391nfs_mark_request_dirty(struct nfs_page *req)
392{
393 struct inode *inode = req->wb_context->dentry->d_inode;
394 struct nfs_inode *nfsi = NFS_I(inode);
395
396 spin_lock(&nfsi->req_lock);
397 radix_tree_tag_set(&nfsi->nfs_page_tree,
398 req->wb_index, NFS_PAGE_TAG_DIRTY);
399 nfs_list_add_request(req, &nfsi->dirty);
400 nfsi->ndirty++;
401 spin_unlock(&nfsi->req_lock);
402 __mark_inode_dirty(inode, I_DIRTY_PAGES);
403}
404
405static void 425static void
406nfs_redirty_request(struct nfs_page *req) 426nfs_redirty_request(struct nfs_page *req)
407{ 427{
408 clear_bit(PG_FLUSHING, &req->wb_flags);
409 __set_page_dirty_nobuffers(req->wb_page); 428 __set_page_dirty_nobuffers(req->wb_page);
410} 429}
411 430
@@ -415,7 +434,11 @@ nfs_redirty_request(struct nfs_page *req)
415static inline int 434static inline int
416nfs_dirty_request(struct nfs_page *req) 435nfs_dirty_request(struct nfs_page *req)
417{ 436{
418 return test_bit(PG_FLUSHING, &req->wb_flags) == 0; 437 struct page *page = req->wb_page;
438
439 if (page == NULL || test_bit(PG_NEED_COMMIT, &req->wb_flags))
440 return 0;
441 return !PageWriteback(req->wb_page);
419} 442}
420 443
421#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 444#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
@@ -431,10 +454,48 @@ nfs_mark_request_commit(struct nfs_page *req)
431 spin_lock(&nfsi->req_lock); 454 spin_lock(&nfsi->req_lock);
432 nfs_list_add_request(req, &nfsi->commit); 455 nfs_list_add_request(req, &nfsi->commit);
433 nfsi->ncommit++; 456 nfsi->ncommit++;
457 set_bit(PG_NEED_COMMIT, &(req)->wb_flags);
434 spin_unlock(&nfsi->req_lock); 458 spin_unlock(&nfsi->req_lock);
435 inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 459 inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
436 __mark_inode_dirty(inode, I_DIRTY_DATASYNC); 460 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
437} 461}
462
463static inline
464int nfs_write_need_commit(struct nfs_write_data *data)
465{
466 return data->verf.committed != NFS_FILE_SYNC;
467}
468
469static inline
470int nfs_reschedule_unstable_write(struct nfs_page *req)
471{
472 if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
473 nfs_mark_request_commit(req);
474 return 1;
475 }
476 if (test_and_clear_bit(PG_NEED_RESCHED, &req->wb_flags)) {
477 nfs_redirty_request(req);
478 return 1;
479 }
480 return 0;
481}
482#else
483static inline void
484nfs_mark_request_commit(struct nfs_page *req)
485{
486}
487
488static inline
489int nfs_write_need_commit(struct nfs_write_data *data)
490{
491 return 0;
492}
493
494static inline
495int nfs_reschedule_unstable_write(struct nfs_page *req)
496{
497 return 0;
498}
438#endif 499#endif
439 500
440/* 501/*
@@ -481,6 +542,7 @@ static void nfs_cancel_dirty_list(struct list_head *head)
481 while(!list_empty(head)) { 542 while(!list_empty(head)) {
482 req = nfs_list_entry(head->next); 543 req = nfs_list_entry(head->next);
483 nfs_list_remove_request(req); 544 nfs_list_remove_request(req);
545 nfs_end_page_writeback(req->wb_page);
484 nfs_inode_remove_request(req); 546 nfs_inode_remove_request(req);
485 nfs_clear_page_writeback(req); 547 nfs_clear_page_writeback(req);
486 } 548 }
@@ -494,6 +556,7 @@ static void nfs_cancel_commit_list(struct list_head *head)
494 req = nfs_list_entry(head->next); 556 req = nfs_list_entry(head->next);
495 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 557 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
496 nfs_list_remove_request(req); 558 nfs_list_remove_request(req);
559 clear_bit(PG_NEED_COMMIT, &(req)->wb_flags);
497 nfs_inode_remove_request(req); 560 nfs_inode_remove_request(req);
498 nfs_unlock_request(req); 561 nfs_unlock_request(req);
499 } 562 }
@@ -531,10 +594,10 @@ static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, un
531} 594}
532#endif 595#endif
533 596
534static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) 597static int nfs_wait_on_write_congestion(struct address_space *mapping)
535{ 598{
599 struct inode *inode = mapping->host;
536 struct backing_dev_info *bdi = mapping->backing_dev_info; 600 struct backing_dev_info *bdi = mapping->backing_dev_info;
537 DEFINE_WAIT(wait);
538 int ret = 0; 601 int ret = 0;
539 602
540 might_sleep(); 603 might_sleep();
@@ -542,31 +605,23 @@ static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr)
542 if (!bdi_write_congested(bdi)) 605 if (!bdi_write_congested(bdi))
543 return 0; 606 return 0;
544 607
545 nfs_inc_stats(mapping->host, NFSIOS_CONGESTIONWAIT); 608 nfs_inc_stats(inode, NFSIOS_CONGESTIONWAIT);
546 609
547 if (intr) { 610 do {
548 struct rpc_clnt *clnt = NFS_CLIENT(mapping->host); 611 struct rpc_clnt *clnt = NFS_CLIENT(inode);
549 sigset_t oldset; 612 sigset_t oldset;
550 613
551 rpc_clnt_sigmask(clnt, &oldset); 614 rpc_clnt_sigmask(clnt, &oldset);
552 prepare_to_wait(&nfs_write_congestion, &wait, TASK_INTERRUPTIBLE); 615 ret = congestion_wait_interruptible(WRITE, HZ/10);
553 if (bdi_write_congested(bdi)) {
554 if (signalled())
555 ret = -ERESTARTSYS;
556 else
557 schedule();
558 }
559 rpc_clnt_sigunmask(clnt, &oldset); 616 rpc_clnt_sigunmask(clnt, &oldset);
560 } else { 617 if (ret == -ERESTARTSYS)
561 prepare_to_wait(&nfs_write_congestion, &wait, TASK_UNINTERRUPTIBLE); 618 break;
562 if (bdi_write_congested(bdi)) 619 ret = 0;
563 schedule(); 620 } while (bdi_write_congested(bdi));
564 } 621
565 finish_wait(&nfs_write_congestion, &wait);
566 return ret; 622 return ret;
567} 623}
568 624
569
570/* 625/*
571 * Try to update any existing write request, or create one if there is none. 626 * Try to update any existing write request, or create one if there is none.
572 * In order to match, the request's credentials must match those of 627 * In order to match, the request's credentials must match those of
@@ -577,14 +632,15 @@ static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr)
577static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, 632static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx,
578 struct page *page, unsigned int offset, unsigned int bytes) 633 struct page *page, unsigned int offset, unsigned int bytes)
579{ 634{
580 struct inode *inode = page->mapping->host; 635 struct address_space *mapping = page->mapping;
636 struct inode *inode = mapping->host;
581 struct nfs_inode *nfsi = NFS_I(inode); 637 struct nfs_inode *nfsi = NFS_I(inode);
582 struct nfs_page *req, *new = NULL; 638 struct nfs_page *req, *new = NULL;
583 unsigned long rqend, end; 639 unsigned long rqend, end;
584 640
585 end = offset + bytes; 641 end = offset + bytes;
586 642
587 if (nfs_wait_on_write_congestion(page->mapping, NFS_SERVER(inode)->flags & NFS_MOUNT_INTR)) 643 if (nfs_wait_on_write_congestion(mapping))
588 return ERR_PTR(-ERESTARTSYS); 644 return ERR_PTR(-ERESTARTSYS);
589 for (;;) { 645 for (;;) {
590 /* Loop over all inode entries and see if we find 646 /* Loop over all inode entries and see if we find
@@ -727,26 +783,12 @@ int nfs_updatepage(struct file *file, struct page *page,
727 783
728static void nfs_writepage_release(struct nfs_page *req) 784static void nfs_writepage_release(struct nfs_page *req)
729{ 785{
730 end_page_writeback(req->wb_page);
731 786
732#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 787 if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) {
733 if (!PageError(req->wb_page)) { 788 nfs_end_page_writeback(req->wb_page);
734 if (NFS_NEED_RESCHED(req)) { 789 nfs_inode_remove_request(req);
735 nfs_redirty_request(req); 790 } else
736 goto out; 791 nfs_end_page_writeback(req->wb_page);
737 } else if (NFS_NEED_COMMIT(req)) {
738 nfs_mark_request_commit(req);
739 goto out;
740 }
741 }
742 nfs_inode_remove_request(req);
743
744out:
745 nfs_clear_commit(req);
746 nfs_clear_reschedule(req);
747#else
748 nfs_inode_remove_request(req);
749#endif
750 nfs_clear_page_writeback(req); 792 nfs_clear_page_writeback(req);
751} 793}
752 794
@@ -879,6 +921,7 @@ out_bad:
879 nfs_writedata_release(data); 921 nfs_writedata_release(data);
880 } 922 }
881 nfs_redirty_request(req); 923 nfs_redirty_request(req);
924 nfs_end_page_writeback(req->wb_page);
882 nfs_clear_page_writeback(req); 925 nfs_clear_page_writeback(req);
883 return -ENOMEM; 926 return -ENOMEM;
884} 927}
@@ -924,6 +967,7 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how)
924 struct nfs_page *req = nfs_list_entry(head->next); 967 struct nfs_page *req = nfs_list_entry(head->next);
925 nfs_list_remove_request(req); 968 nfs_list_remove_request(req);
926 nfs_redirty_request(req); 969 nfs_redirty_request(req);
970 nfs_end_page_writeback(req->wb_page);
927 nfs_clear_page_writeback(req); 971 nfs_clear_page_writeback(req);
928 } 972 }
929 return -ENOMEM; 973 return -ENOMEM;
@@ -959,6 +1003,7 @@ out_err:
959 req = nfs_list_entry(head->next); 1003 req = nfs_list_entry(head->next);
960 nfs_list_remove_request(req); 1004 nfs_list_remove_request(req);
961 nfs_redirty_request(req); 1005 nfs_redirty_request(req);
1006 nfs_end_page_writeback(req->wb_page);
962 nfs_clear_page_writeback(req); 1007 nfs_clear_page_writeback(req);
963 } 1008 }
964 return error; 1009 return error;
@@ -986,22 +1031,28 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
986 nfs_set_pageerror(page); 1031 nfs_set_pageerror(page);
987 req->wb_context->error = task->tk_status; 1032 req->wb_context->error = task->tk_status;
988 dprintk(", error = %d\n", task->tk_status); 1033 dprintk(", error = %d\n", task->tk_status);
989 } else { 1034 goto out;
990#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
991 if (data->verf.committed < NFS_FILE_SYNC) {
992 if (!NFS_NEED_COMMIT(req)) {
993 nfs_defer_commit(req);
994 memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
995 dprintk(" defer commit\n");
996 } else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) {
997 nfs_defer_reschedule(req);
998 dprintk(" server reboot detected\n");
999 }
1000 } else
1001#endif
1002 dprintk(" OK\n");
1003 } 1035 }
1004 1036
1037 if (nfs_write_need_commit(data)) {
1038 spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock;
1039
1040 spin_lock(req_lock);
1041 if (test_bit(PG_NEED_RESCHED, &req->wb_flags)) {
1042 /* Do nothing we need to resend the writes */
1043 } else if (!test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags)) {
1044 memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
1045 dprintk(" defer commit\n");
1046 } else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) {
1047 set_bit(PG_NEED_RESCHED, &req->wb_flags);
1048 clear_bit(PG_NEED_COMMIT, &req->wb_flags);
1049 dprintk(" server reboot detected\n");
1050 }
1051 spin_unlock(req_lock);
1052 } else
1053 dprintk(" OK\n");
1054
1055out:
1005 if (atomic_dec_and_test(&req->wb_complete)) 1056 if (atomic_dec_and_test(&req->wb_complete))
1006 nfs_writepage_release(req); 1057 nfs_writepage_release(req);
1007} 1058}
@@ -1042,25 +1093,21 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
1042 if (task->tk_status < 0) { 1093 if (task->tk_status < 0) {
1043 nfs_set_pageerror(page); 1094 nfs_set_pageerror(page);
1044 req->wb_context->error = task->tk_status; 1095 req->wb_context->error = task->tk_status;
1045 end_page_writeback(page);
1046 nfs_inode_remove_request(req);
1047 dprintk(", error = %d\n", task->tk_status); 1096 dprintk(", error = %d\n", task->tk_status);
1048 goto next; 1097 goto remove_request;
1049 } 1098 }
1050 end_page_writeback(page);
1051 1099
1052#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 1100 if (nfs_write_need_commit(data)) {
1053 if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) { 1101 memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf));
1054 nfs_inode_remove_request(req); 1102 nfs_mark_request_commit(req);
1055 dprintk(" OK\n"); 1103 nfs_end_page_writeback(page);
1104 dprintk(" marked for commit\n");
1056 goto next; 1105 goto next;
1057 } 1106 }
1058 memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); 1107 dprintk(" OK\n");
1059 nfs_mark_request_commit(req); 1108remove_request:
1060 dprintk(" marked for commit\n"); 1109 nfs_end_page_writeback(page);
1061#else
1062 nfs_inode_remove_request(req); 1110 nfs_inode_remove_request(req);
1063#endif
1064 next: 1111 next:
1065 nfs_clear_page_writeback(req); 1112 nfs_clear_page_writeback(req);
1066 } 1113 }
@@ -1248,6 +1295,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1248 while (!list_empty(&data->pages)) { 1295 while (!list_empty(&data->pages)) {
1249 req = nfs_list_entry(data->pages.next); 1296 req = nfs_list_entry(data->pages.next);
1250 nfs_list_remove_request(req); 1297 nfs_list_remove_request(req);
1298 clear_bit(PG_NEED_COMMIT, &(req)->wb_flags);
1251 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); 1299 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
1252 1300
1253 dprintk("NFS: commit (%s/%Ld %d@%Ld)", 1301 dprintk("NFS: commit (%s/%Ld %d@%Ld)",
@@ -1483,15 +1531,22 @@ int nfs_wb_page(struct inode *inode, struct page* page)
1483 1531
1484int nfs_set_page_dirty(struct page *page) 1532int nfs_set_page_dirty(struct page *page)
1485{ 1533{
1534 spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock;
1486 struct nfs_page *req; 1535 struct nfs_page *req;
1536 int ret;
1487 1537
1488 req = nfs_page_find_request(page); 1538 spin_lock(req_lock);
1539 req = nfs_page_find_request_locked(page);
1489 if (req != NULL) { 1540 if (req != NULL) {
1490 /* Mark any existing write requests for flushing */ 1541 /* Mark any existing write requests for flushing */
1491 set_bit(PG_NEED_FLUSH, &req->wb_flags); 1542 ret = !test_and_set_bit(PG_NEED_FLUSH, &req->wb_flags);
1543 spin_unlock(req_lock);
1492 nfs_release_request(req); 1544 nfs_release_request(req);
1545 return ret;
1493 } 1546 }
1494 return __set_page_dirty_nobuffers(page); 1547 ret = __set_page_dirty_nobuffers(page);
1548 spin_unlock(req_lock);
1549 return ret;
1495} 1550}
1496 1551
1497 1552
@@ -1514,6 +1569,26 @@ int __init nfs_init_writepagecache(void)
1514 if (nfs_commit_mempool == NULL) 1569 if (nfs_commit_mempool == NULL)
1515 return -ENOMEM; 1570 return -ENOMEM;
1516 1571
1572 /*
1573 * NFS congestion size, scale with available memory.
1574 *
1575 * 64MB: 8192k
1576 * 128MB: 11585k
1577 * 256MB: 16384k
1578 * 512MB: 23170k
1579 * 1GB: 32768k
1580 * 2GB: 46340k
1581 * 4GB: 65536k
1582 * 8GB: 92681k
1583 * 16GB: 131072k
1584 *
1585 * This allows larger machines to have larger/more transfers.
1586 * Limit the default to 256M
1587 */
1588 nfs_congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10);
1589 if (nfs_congestion_kb > 256*1024)
1590 nfs_congestion_kb = 256*1024;
1591
1517 return 0; 1592 return 0;
1518} 1593}
1519 1594