@@ -431,8 +431,15 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
/* If PagePrivate() is set, then the page is not freeable */
if (PagePrivate(page))
- return 0;
- return nfs_fscache_release_page(page, gfp);
+ return false;
+
+ if (PageFsCache(page)) {
+ if (!(gfp & __GFP_DIRECT_RECLAIM) || !(gfp & __GFP_FS))
+ return false;
+ wait_on_page_fscache(page);
+ }
+
+ return true;
}
static void nfs_check_dirty_writeback(struct page *page,
@@ -332,30 +332,6 @@ void nfs_fscache_open_file(struct inode *inode, struct file *filp)
EXPORT_SYMBOL_GPL(nfs_fscache_open_file);
/*
- * 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)
-{
- if (PageFsCache(page)) {
- struct fscache_cookie *cookie = nfs_i_fscache(page->mapping->host);
-
- BUG_ON(!cookie);
- dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n",
- cookie, page, NFS_I(page->mapping->host));
-
- if (!fscache_maybe_release_page(cookie, page, gfp))
- return 0;
-
- nfs_inc_fscache_stats(page->mapping->host,
- NFSIOS_FSCACHE_PAGES_UNCACHED);
- }
-
- return 1;
-}
-
-/*
* Release the caching state associated with a page if undergoing complete page
* invalidation.
*/
@@ -94,7 +94,6 @@ struct nfs_fscache_inode_auxdata {
extern void nfs_fscache_open_file(struct inode *, struct file *);
extern void __nfs_fscache_invalidate_page(struct page *, struct inode *);
-extern int nfs_fscache_release_page(struct page *, gfp_t);
extern int nfs_readpage_from_fscache(struct file *file,
struct page *page,
struct nfs_readdesc *desc);
@@ -163,10 +162,6 @@ static inline void nfs_fscache_clear_inode(struct inode *inode) {}
static inline void nfs_fscache_open_file(struct inode *inode,
struct file *filp) {}
-static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp)
-{
- return 1; /* True: may release page */
-}
static inline void nfs_fscache_invalidate_page(struct page *page,
struct inode *inode) {}
static inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi,
@@ -2102,17 +2102,15 @@ int nfs_migrate_page(struct address_space *mapping, struct page *newpage,
struct page *page, enum migrate_mode mode)
{
/*
- * If PagePrivate is set, then the page is currently associated with
- * an in-progress read or write request. Don't try to migrate it.
+ * If PagePrivate or PageFsCache is set, then the page is currently
+ * associated with an in-progress read or write request. Don't try
+ * to migrate it.
*
* FIXME: we could do this in principle, but we'll need a way to ensure
* that we can safely release the inode reference while holding
* the page lock.
*/
- if (PagePrivate(page))
- return -EBUSY;
-
- if (!nfs_fscache_release_page(page, GFP_KERNEL))
+ if (PagePrivate(page) || PageFsCache(page))
return -EBUSY;
return migrate_page(mapping, newpage, page, mode);
When using the new fscache kiocb IO API, netfs callers should no longer use fscache_maybe_release_page() in releasepage, but instead should just wait PG_fscache as needed. The PG_fscache page bit now means the page is being written to the cache. Signed-off-by: Dave Wysochanski <dwysocha@redhat.com> --- fs/nfs/file.c | 11 +++++++++-- fs/nfs/fscache.c | 24 ------------------------ fs/nfs/fscache.h | 5 ----- fs/nfs/write.c | 10 ++++------ 4 files changed, 13 insertions(+), 37 deletions(-)