diff options
author | David Howells <dhowells@redhat.com> | 2009-04-03 11:42:44 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2009-04-03 11:42:44 -0400 |
commit | 545db45f0fc0d4203b045047798ce156972a3056 (patch) | |
tree | 783db1091f5d6f21dafece81f6c94caf0aec98b8 /fs/nfs/file.c | |
parent | 6a51091d0775cdc4a923f2172c61925ad416aa32 (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.c | 18 |
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 | */ |
419 | static void nfs_invalidate_page(struct page *page, unsigned long offset) | 420 | static 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 | */ |
451 | static int nfs_launder_page(struct page *page) | 456 | static 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) |