diff options
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r-- | fs/nfs/file.c | 52 |
1 files changed, 40 insertions, 12 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 524dd80d1898..6920127c5eb7 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "internal.h" | 36 | #include "internal.h" |
37 | #include "iostat.h" | 37 | #include "iostat.h" |
38 | #include "fscache.h" | 38 | #include "fscache.h" |
39 | #include "pnfs.h" | ||
39 | 40 | ||
40 | #include "nfstrace.h" | 41 | #include "nfstrace.h" |
41 | 42 | ||
@@ -327,6 +328,12 @@ static int nfs_want_read_modify_write(struct file *file, struct page *page, | |||
327 | unsigned int offset = pos & (PAGE_CACHE_SIZE - 1); | 328 | unsigned int offset = pos & (PAGE_CACHE_SIZE - 1); |
328 | unsigned int end = offset + len; | 329 | unsigned int end = offset + len; |
329 | 330 | ||
331 | if (pnfs_ld_read_whole_page(file->f_mapping->host)) { | ||
332 | if (!PageUptodate(page)) | ||
333 | return 1; | ||
334 | return 0; | ||
335 | } | ||
336 | |||
330 | if ((file->f_mode & FMODE_READ) && /* open for read? */ | 337 | if ((file->f_mode & FMODE_READ) && /* open for read? */ |
331 | !PageUptodate(page) && /* Uptodate? */ | 338 | !PageUptodate(page) && /* Uptodate? */ |
332 | !PagePrivate(page) && /* i/o request already? */ | 339 | !PagePrivate(page) && /* i/o request already? */ |
@@ -468,17 +475,26 @@ static int nfs_release_page(struct page *page, gfp_t gfp) | |||
468 | 475 | ||
469 | dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); | 476 | dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); |
470 | 477 | ||
471 | /* Only do I/O if gfp is a superset of GFP_KERNEL, and we're not | 478 | /* Always try to initiate a 'commit' if relevant, but only |
472 | * doing this memory reclaim for a fs-related allocation. | 479 | * wait for it if __GFP_WAIT is set. Even then, only wait 1 |
480 | * second and only if the 'bdi' is not congested. | ||
481 | * Waiting indefinitely can cause deadlocks when the NFS | ||
482 | * server is on this machine, when a new TCP connection is | ||
483 | * needed and in other rare cases. There is no particular | ||
484 | * need to wait extensively here. A short wait has the | ||
485 | * benefit that someone else can worry about the freezer. | ||
473 | */ | 486 | */ |
474 | if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL && | 487 | if (mapping) { |
475 | !(current->flags & PF_FSTRANS)) { | 488 | struct nfs_server *nfss = NFS_SERVER(mapping->host); |
476 | int how = FLUSH_SYNC; | 489 | nfs_commit_inode(mapping->host, 0); |
477 | 490 | if ((gfp & __GFP_WAIT) && | |
478 | /* Don't let kswapd deadlock waiting for OOM RPC calls */ | 491 | !bdi_write_congested(&nfss->backing_dev_info)) { |
479 | if (current_is_kswapd()) | 492 | wait_on_page_bit_killable_timeout(page, PG_private, |
480 | how = 0; | 493 | HZ); |
481 | nfs_commit_inode(mapping->host, how); | 494 | if (PagePrivate(page)) |
495 | set_bdi_congested(&nfss->backing_dev_info, | ||
496 | BLK_RW_ASYNC); | ||
497 | } | ||
482 | } | 498 | } |
483 | /* If PagePrivate() is set, then the page is not freeable */ | 499 | /* If PagePrivate() is set, then the page is not freeable */ |
484 | if (PagePrivate(page)) | 500 | if (PagePrivate(page)) |
@@ -539,13 +555,25 @@ static int nfs_launder_page(struct page *page) | |||
539 | static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file, | 555 | static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file, |
540 | sector_t *span) | 556 | sector_t *span) |
541 | { | 557 | { |
558 | int ret; | ||
559 | struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host); | ||
560 | |||
542 | *span = sis->pages; | 561 | *span = sis->pages; |
543 | return xs_swapper(NFS_CLIENT(file->f_mapping->host)->cl_xprt, 1); | 562 | |
563 | rcu_read_lock(); | ||
564 | ret = xs_swapper(rcu_dereference(clnt->cl_xprt), 1); | ||
565 | rcu_read_unlock(); | ||
566 | |||
567 | return ret; | ||
544 | } | 568 | } |
545 | 569 | ||
546 | static void nfs_swap_deactivate(struct file *file) | 570 | static void nfs_swap_deactivate(struct file *file) |
547 | { | 571 | { |
548 | xs_swapper(NFS_CLIENT(file->f_mapping->host)->cl_xprt, 0); | 572 | struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host); |
573 | |||
574 | rcu_read_lock(); | ||
575 | xs_swapper(rcu_dereference(clnt->cl_xprt), 0); | ||
576 | rcu_read_unlock(); | ||
549 | } | 577 | } |
550 | #endif | 578 | #endif |
551 | 579 | ||