diff options
author | David Howells <dhowells@redhat.com> | 2009-04-03 16:42:44 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2009-04-03 16:42:44 +0100 |
commit | 545db45f0fc0d4203b045047798ce156972a3056 (patch) | |
tree | 783db1091f5d6f21dafece81f6c94caf0aec98b8 /fs/nfs/fscache.c | |
parent | 6a51091d0775cdc4a923f2172c61925ad416aa32 (diff) | |
download | linux-545db45f0fc0d4203b045047798ce156972a3056.tar.gz linux-545db45f0fc0d4203b045047798ce156972a3056.tar.bz2 linux-545db45f0fc0d4203b045047798ce156972a3056.zip |
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/fscache.c')
-rw-r--r-- | fs/nfs/fscache.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index e3816eb53fb8..f673d35d8b89 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c @@ -19,6 +19,7 @@ #include <linux/seq_file.h> #include "internal.h" +#include "iostat.h" #include "fscache.h" #define NFSDBG_FACILITY NFSDBG_FSCACHE @@ -328,3 +329,55 @@ void nfs_fscache_reset_inode_cookie(struct inode *inode) } nfs_fscache_inode_unlock(inode); } + +/* + * Release the caching state associated with a page, if the page isn't busy + * interacting with the cache. + * - Returns true (can release page) or false (page busy). + */ +int nfs_fscache_release_page(struct page *page, gfp_t gfp) +{ + struct nfs_inode *nfsi = NFS_I(page->mapping->host); + struct fscache_cookie *cookie = nfsi->fscache; + + BUG_ON(!cookie); + + if (fscache_check_page_write(cookie, page)) { + if (!(gfp & __GFP_WAIT)) + return 0; + fscache_wait_on_page_write(cookie, page); + } + + if (PageFsCache(page)) { + dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", + cookie, page, nfsi); + + fscache_uncache_page(cookie, page); + nfs_add_fscache_stats(page->mapping->host, + NFSIOS_FSCACHE_PAGES_UNCACHED, 1); + } + + return 1; +} + +/* + * Release the caching state associated with a page if undergoing complete page + * invalidation. + */ +void __nfs_fscache_invalidate_page(struct page *page, struct inode *inode) +{ + struct nfs_inode *nfsi = NFS_I(inode); + struct fscache_cookie *cookie = nfsi->fscache; + + BUG_ON(!cookie); + + dfprintk(FSCACHE, "NFS: fscache invalidatepage (0x%p/0x%p/0x%p)\n", + cookie, page, nfsi); + + fscache_wait_on_page_write(cookie, page); + + BUG_ON(!PageLocked(page)); + fscache_uncache_page(cookie, page); + nfs_add_fscache_stats(page->mapping->host, + NFSIOS_FSCACHE_PAGES_UNCACHED, 1); +} |