aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r--fs/nfs/file.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index a87a44f84113..94e94bd11aae 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -451,11 +451,13 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
451 * - Called if either PG_private or PG_fscache is set on the page 451 * - Called if either PG_private or PG_fscache is set on the page
452 * - Caller holds page lock 452 * - Caller holds page lock
453 */ 453 */
454static void nfs_invalidate_page(struct page *page, unsigned long offset) 454static void nfs_invalidate_page(struct page *page, unsigned int offset,
455 unsigned int length)
455{ 456{
456 dfprintk(PAGECACHE, "NFS: invalidate_page(%p, %lu)\n", page, offset); 457 dfprintk(PAGECACHE, "NFS: invalidate_page(%p, %u, %u)\n",
458 page, offset, length);
457 459
458 if (offset != 0) 460 if (offset != 0 || length < PAGE_CACHE_SIZE)
459 return; 461 return;
460 /* Cancel any unstarted writes on this page */ 462 /* Cancel any unstarted writes on this page */
461 nfs_wb_page_cancel(page_file_mapping(page)->host, page); 463 nfs_wb_page_cancel(page_file_mapping(page)->host, page);
@@ -493,6 +495,35 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
493 return nfs_fscache_release_page(page, gfp); 495 return nfs_fscache_release_page(page, gfp);
494} 496}
495 497
498static void nfs_check_dirty_writeback(struct page *page,
499 bool *dirty, bool *writeback)
500{
501 struct nfs_inode *nfsi;
502 struct address_space *mapping = page_file_mapping(page);
503
504 if (!mapping || PageSwapCache(page))
505 return;
506
507 /*
508 * Check if an unstable page is currently being committed and
509 * if so, have the VM treat it as if the page is under writeback
510 * so it will not block due to pages that will shortly be freeable.
511 */
512 nfsi = NFS_I(mapping->host);
513 if (test_bit(NFS_INO_COMMIT, &nfsi->flags)) {
514 *writeback = true;
515 return;
516 }
517
518 /*
519 * If PagePrivate() is set, then the page is not freeable and as the
520 * inode is not being committed, it's not going to be cleaned in the
521 * near future so treat it as dirty
522 */
523 if (PagePrivate(page))
524 *dirty = true;
525}
526
496/* 527/*
497 * Attempt to clear the private state associated with a page when an error 528 * Attempt to clear the private state associated with a page when an error
498 * occurs that requires the cached contents of an inode to be written back or 529 * occurs that requires the cached contents of an inode to be written back or
@@ -540,6 +571,7 @@ const struct address_space_operations nfs_file_aops = {
540 .direct_IO = nfs_direct_IO, 571 .direct_IO = nfs_direct_IO,
541 .migratepage = nfs_migrate_page, 572 .migratepage = nfs_migrate_page,
542 .launder_page = nfs_launder_page, 573 .launder_page = nfs_launder_page,
574 .is_dirty_writeback = nfs_check_dirty_writeback,
543 .error_remove_page = generic_error_remove_page, 575 .error_remove_page = generic_error_remove_page,
544#ifdef CONFIG_NFS_SWAP 576#ifdef CONFIG_NFS_SWAP
545 .swap_activate = nfs_swap_activate, 577 .swap_activate = nfs_swap_activate,