aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/file.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2009-04-03 11:42:44 -0400
committerDavid Howells <dhowells@redhat.com>2009-04-03 11:42:44 -0400
commit545db45f0fc0d4203b045047798ce156972a3056 (patch)
tree783db1091f5d6f21dafece81f6c94caf0aec98b8 /fs/nfs/file.c
parent6a51091d0775cdc4a923f2172c61925ad416aa32 (diff)
NFS: FS-Cache page management
FS-Cache page management for NFS. This includes hooking the releasing and invalidation of pages marked with PG_fscache (aka PG_private_2) and waiting for completion of the write-to-cache flag (PG_fscache_write aka PG_owner_priv_2). Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: Steve Dickson <steved@redhat.com> Acked-by: Trond Myklebust <Trond.Myklebust@netapp.com> Acked-by: Al Viro <viro@zeniv.linux.org.uk> Tested-by: Daire Byrne <Daire.Byrne@framestore.com>
Diffstat (limited to 'fs/nfs/file.c')
-rw-r--r--fs/nfs/file.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index f5bc54dccecb..3523b895eb4b 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -35,6 +35,7 @@
35#include "delegation.h" 35#include "delegation.h"
36#include "internal.h" 36#include "internal.h"
37#include "iostat.h" 37#include "iostat.h"
38#include "fscache.h"
38 39
39#define NFSDBG_FACILITY NFSDBG_FILE 40#define NFSDBG_FACILITY NFSDBG_FILE
40 41
@@ -413,7 +414,7 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
413 * Partially or wholly invalidate a page 414 * Partially or wholly invalidate a page
414 * - Release the private state associated with a page if undergoing complete 415 * - Release the private state associated with a page if undergoing complete
415 * page invalidation 416 * page invalidation
416 * - Called if either PG_private or PG_private_2 is set on the page 417 * - Called if either PG_private or PG_fscache is set on the page
417 * - Caller holds page lock 418 * - Caller holds page lock
418 */ 419 */
419static void nfs_invalidate_page(struct page *page, unsigned long offset) 420static void nfs_invalidate_page(struct page *page, unsigned long offset)
@@ -424,11 +425,13 @@ static void nfs_invalidate_page(struct page *page, unsigned long offset)
424 return; 425 return;
425 /* Cancel any unstarted writes on this page */ 426 /* Cancel any unstarted writes on this page */
426 nfs_wb_page_cancel(page->mapping->host, page); 427 nfs_wb_page_cancel(page->mapping->host, page);
428
429 nfs_fscache_invalidate_page(page, page->mapping->host);
427} 430}
428 431
429/* 432/*
430 * Attempt to release the private state associated with a page 433 * Attempt to release the private state associated with a page
431 * - Called if either PG_private or PG_private_2 is set on the page 434 * - Called if either PG_private or PG_fscache is set on the page
432 * - Caller holds page lock 435 * - Caller holds page lock
433 * - Return true (may release page) or false (may not) 436 * - Return true (may release page) or false (may not)
434 */ 437 */
@@ -437,24 +440,28 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
437 dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); 440 dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
438 441
439 /* If PagePrivate() is set, then the page is not freeable */ 442 /* If PagePrivate() is set, then the page is not freeable */
440 return 0; 443 if (PagePrivate(page))
444 return 0;
445 return nfs_fscache_release_page(page, gfp);
441} 446}
442 447
443/* 448/*
444 * Attempt to clear the private state associated with a page when an error 449 * Attempt to clear the private state associated with a page when an error
445 * occurs that requires the cached contents of an inode to be written back or 450 * occurs that requires the cached contents of an inode to be written back or
446 * destroyed 451 * destroyed
447 * - Called if either PG_private or PG_private_2 is set on the page 452 * - Called if either PG_private or fscache is set on the page
448 * - Caller holds page lock 453 * - Caller holds page lock
449 * - Return 0 if successful, -error otherwise 454 * - Return 0 if successful, -error otherwise
450 */ 455 */
451static int nfs_launder_page(struct page *page) 456static int nfs_launder_page(struct page *page)
452{ 457{
453 struct inode *inode = page->mapping->host; 458 struct inode *inode = page->mapping->host;
459 struct nfs_inode *nfsi = NFS_I(inode);
454 460
455 dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n", 461 dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n",
456 inode->i_ino, (long long)page_offset(page)); 462 inode->i_ino, (long long)page_offset(page));
457 463
464 nfs_fscache_wait_on_page_write(nfsi, page);
458 return nfs_wb_page(inode, page); 465 return nfs_wb_page(inode, page);
459} 466}
460 467
@@ -491,6 +498,9 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
491 filp->f_mapping->host->i_ino, 498 filp->f_mapping->host->i_ino,
492 (long long)page_offset(page)); 499 (long long)page_offset(page));
493 500
501 /* make sure the cache has finished storing the page */
502 nfs_fscache_wait_on_page_write(NFS_I(dentry->d_inode), page);
503
494 lock_page(page); 504 lock_page(page);
495 mapping = page->mapping; 505 mapping = page->mapping;
496 if (mapping != dentry->d_inode->i_mapping) 506 if (mapping != dentry->d_inode->i_mapping)