From 545db45f0fc0d4203b045047798ce156972a3056 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 3 Apr 2009 16:42:44 +0100 Subject: 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 Acked-by: Steve Dickson Acked-by: Trond Myklebust Acked-by: Al Viro Tested-by: Daire Byrne --- fs/nfs/fscache.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'fs/nfs/fscache.c') 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 #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); +} -- cgit v1.2.3-59-g8ed1b