Commit a6b5a28e authored by Dave Wysochanski's avatar Dave Wysochanski Committed by David Howells

nfs: Convert to new fscache volume/cookie API

Change the nfs filesystem to support fscache's indexing rewrite and
reenable caching in nfs.

The following changes have been made:

 (1) The fscache_netfs struct is no more, and there's no need to register
     the filesystem as a whole.

 (2) The session cookie is now an fscache_volume cookie, allocated with
     fscache_acquire_volume().  That takes three parameters: a string
     representing the "volume" in the index, a string naming the cache to
     use (or NULL) and a u64 that conveys coherency metadata for the
     volume.

     For nfs, I've made it render the volume name string as:

        "nfs,<ver>,<family>,<address>,<port>,<fsidH>,<fsidL>*<,param>[,<uniq>]"

 (3) The fscache_cookie_def is no more and needed information is passed
     directly to fscache_acquire_cookie().  The cache no longer calls back
     into the filesystem, but rather metadata changes are indicated at
     other times.

     fscache_acquire_cookie() is passed the same keying and coherency
     information as before.

 (4) fscache_enable/disable_cookie() have been removed.

     Call fscache_use_cookie() and fscache_unuse_cookie() when a file is
     opened or closed to prevent a cache file from being culled and to keep
     resources to hand that are needed to do I/O.

     If a file is opened for writing, we invalidate it with
     FSCACHE_INVAL_DIO_WRITE in lieu of doing writeback to the cache,
     thereby making it cease caching until all currently open files are
     closed.  This should give the same behaviour as the uptream code.
     Making the cache store local modifications isn't straightforward for
     NFS, so that's left for future patches.

 (5) fscache_invalidate() now needs to be given uptodate auxiliary data and
     a file size.  It also takes a flag to indicate if this was due to a
     DIO write.

 (6) Call nfs_fscache_invalidate() with FSCACHE_INVAL_DIO_WRITE on a file
     to which a DIO write is made.

 (7) Call fscache_note_page_release() from nfs_release_page().

 (8) Use a killable wait in nfs_vm_page_mkwrite() when waiting for
     PG_fscache to be cleared.

 (9) The functions to read and write data to/from the cache are stubbed out
     pending a conversion to use netfslib.

Changes
=======
ver #3:
 - Added missing =n fallback for nfs_fscache_release_file()[1][2].

ver #2:
 - Use gfpflags_allow_blocking() rather than using flag directly.
 - fscache_acquire_volume() now returns errors.
 - Remove NFS_INO_FSCACHE as it's no longer used.
 - Need to unuse a cookie on file-release, not inode-clear.
Signed-off-by: default avatarDave Wysochanski <dwysocha@redhat.com>
Co-developed-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Tested-by: default avatarDave Wysochanski <dwysocha@redhat.com>
Acked-by: default avatarJeff Layton <jlayton@kernel.org>
cc: Trond Myklebust <trond.myklebust@hammerspace.com>
cc: Anna Schumaker <anna.schumaker@netapp.com>
cc: linux-nfs@vger.kernel.org
cc: linux-cachefs@redhat.com
Link: https://lore.kernel.org/r/202112100804.nksO8K4u-lkp@intel.com/ [1]
Link: https://lore.kernel.org/r/202112100957.2oEDT20W-lkp@intel.com/ [2]
Link: https://lore.kernel.org/r/163819668938.215744.14448852181937731615.stgit@warthog.procyon.org.uk/ # v1
Link: https://lore.kernel.org/r/163906979003.143852.2601189243864854724.stgit@warthog.procyon.org.uk/ # v2
Link: https://lore.kernel.org/r/163967182112.1823006.7791504655391213379.stgit@warthog.procyon.org.uk/ # v3
Link: https://lore.kernel.org/r/164021575950.640689.12069642327533368467.stgit@warthog.procyon.org.uk/ # v4
parent 93c84614
...@@ -170,7 +170,7 @@ config ROOT_NFS ...@@ -170,7 +170,7 @@ config ROOT_NFS
config NFS_FSCACHE config NFS_FSCACHE
bool "Provide NFS client caching support" bool "Provide NFS client caching support"
depends on NFS_FS=m && FSCACHE_OLD_API || NFS_FS=y && FSCACHE_OLD_API=y depends on NFS_FS=m && FSCACHE || NFS_FS=y && FSCACHE=y
help help
Say Y here if you want NFS data to be cached locally on disc through Say Y here if you want NFS data to be cached locally on disc through
the general filesystem cache manager the general filesystem cache manager
......
...@@ -12,7 +12,7 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \ ...@@ -12,7 +12,7 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
export.o sysfs.o fs_context.o export.o sysfs.o fs_context.o
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
nfs-$(CONFIG_SYSCTL) += sysctl.o nfs-$(CONFIG_SYSCTL) += sysctl.o
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o nfs-$(CONFIG_NFS_FSCACHE) += fscache.o
obj-$(CONFIG_NFS_V2) += nfsv2.o obj-$(CONFIG_NFS_V2) += nfsv2.o
nfsv2-y := nfs2super.o proc.o nfs2xdr.o nfsv2-y := nfs2super.o proc.o nfs2xdr.o
......
...@@ -183,8 +183,6 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) ...@@ -183,8 +183,6 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
clp->cl_net = get_net(cl_init->net); clp->cl_net = get_net(cl_init->net);
clp->cl_principal = "*"; clp->cl_principal = "*";
nfs_fscache_get_client_cookie(clp);
return clp; return clp;
error_cleanup: error_cleanup:
...@@ -238,8 +236,6 @@ static void pnfs_init_server(struct nfs_server *server) ...@@ -238,8 +236,6 @@ static void pnfs_init_server(struct nfs_server *server)
*/ */
void nfs_free_client(struct nfs_client *clp) void nfs_free_client(struct nfs_client *clp)
{ {
nfs_fscache_release_client_cookie(clp);
/* -EIO all pending I/O */ /* -EIO all pending I/O */
if (!IS_ERR(clp->cl_rpcclient)) if (!IS_ERR(clp->cl_rpcclient))
rpc_shutdown_client(clp->cl_rpcclient); rpc_shutdown_client(clp->cl_rpcclient);
......
...@@ -59,6 +59,7 @@ ...@@ -59,6 +59,7 @@
#include "internal.h" #include "internal.h"
#include "iostat.h" #include "iostat.h"
#include "pnfs.h" #include "pnfs.h"
#include "fscache.h"
#define NFSDBG_FACILITY NFSDBG_VFS #define NFSDBG_FACILITY NFSDBG_VFS
...@@ -959,6 +960,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter) ...@@ -959,6 +960,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
} else { } else {
result = requested; result = requested;
} }
nfs_fscache_invalidate(inode, FSCACHE_INVAL_DIO_WRITE);
out_release: out_release:
nfs_direct_req_release(dreq); nfs_direct_req_release(dreq);
out: out:
......
...@@ -84,6 +84,7 @@ nfs_file_release(struct inode *inode, struct file *filp) ...@@ -84,6 +84,7 @@ nfs_file_release(struct inode *inode, struct file *filp)
nfs_inc_stats(inode, NFSIOS_VFSRELEASE); nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
nfs_file_clear_open_context(filp); nfs_file_clear_open_context(filp);
nfs_fscache_release_file(inode, filp);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(nfs_file_release); EXPORT_SYMBOL_GPL(nfs_file_release);
...@@ -415,8 +416,7 @@ static void nfs_invalidate_page(struct page *page, unsigned int offset, ...@@ -415,8 +416,7 @@ static void nfs_invalidate_page(struct page *page, unsigned int offset,
return; return;
/* Cancel any unstarted writes on this page */ /* Cancel any unstarted writes on this page */
nfs_wb_page_cancel(page_file_mapping(page)->host, page); nfs_wb_page_cancel(page_file_mapping(page)->host, page);
wait_on_page_fscache(page);
nfs_fscache_invalidate_page(page, page->mapping->host);
} }
/* /*
...@@ -475,12 +475,11 @@ static void nfs_check_dirty_writeback(struct page *page, ...@@ -475,12 +475,11 @@ static void nfs_check_dirty_writeback(struct page *page,
static int nfs_launder_page(struct page *page) static int nfs_launder_page(struct page *page)
{ {
struct inode *inode = page_file_mapping(page)->host; struct inode *inode = page_file_mapping(page)->host;
struct nfs_inode *nfsi = NFS_I(inode);
dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n", dfprintk(PAGECACHE, "NFS: launder_page(%ld, %llu)\n",
inode->i_ino, (long long)page_offset(page)); inode->i_ino, (long long)page_offset(page));
nfs_fscache_wait_on_page_write(nfsi, page); wait_on_page_fscache(page);
return nfs_wb_page(inode, page); return nfs_wb_page(inode, page);
} }
...@@ -555,7 +554,11 @@ static vm_fault_t nfs_vm_page_mkwrite(struct vm_fault *vmf) ...@@ -555,7 +554,11 @@ static vm_fault_t nfs_vm_page_mkwrite(struct vm_fault *vmf)
sb_start_pagefault(inode->i_sb); sb_start_pagefault(inode->i_sb);
/* make sure the cache has finished storing the page */ /* make sure the cache has finished storing the page */
nfs_fscache_wait_on_page_write(NFS_I(inode), page); if (PageFsCache(page) &&
wait_on_page_fscache_killable(vmf->page) < 0) {
ret = VM_FAULT_RETRY;
goto out;
}
wait_on_bit_action(&NFS_I(inode)->flags, NFS_INO_INVALIDATING, wait_on_bit_action(&NFS_I(inode)->flags, NFS_INO_INVALIDATING,
nfs_wait_bit_killable, TASK_KILLABLE); nfs_wait_bit_killable, TASK_KILLABLE);
......
// SPDX-License-Identifier: GPL-2.0-or-later
/* NFS FS-Cache index structure definition
*
* Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_fs_sb.h>
#include <linux/in6.h>
#include <linux/iversion.h>
#include "internal.h"
#include "fscache.h"
#define NFSDBG_FACILITY NFSDBG_FSCACHE
/*
* Define the NFS filesystem for FS-Cache. Upon registration FS-Cache sticks
* the cookie for the top-level index object for NFS into here. The top-level
* index can than have other cache objects inserted into it.
*/
struct fscache_netfs nfs_fscache_netfs = {
.name = "nfs",
.version = 0,
};
/*
* Register NFS for caching
*/
int nfs_fscache_register(void)
{
return fscache_register_netfs(&nfs_fscache_netfs);
}
/*
* Unregister NFS for caching
*/
void nfs_fscache_unregister(void)
{
fscache_unregister_netfs(&nfs_fscache_netfs);
}
/*
* Define the server object for FS-Cache. This is used to describe a server
* object to fscache_acquire_cookie(). It is keyed by the NFS protocol and
* server address parameters.
*/
const struct fscache_cookie_def nfs_fscache_server_index_def = {
.name = "NFS.server",
.type = FSCACHE_COOKIE_TYPE_INDEX,
};
/*
* Define the superblock object for FS-Cache. This is used to describe a
* superblock object to fscache_acquire_cookie(). It is keyed by all the NFS
* parameters that might cause a separate superblock.
*/
const struct fscache_cookie_def nfs_fscache_super_index_def = {
.name = "NFS.super",
.type = FSCACHE_COOKIE_TYPE_INDEX,
};
/*
* Consult the netfs about the state of an object
* - This function can be absent if the index carries no state data
* - The netfs data from the cookie being used as the target is
* presented, as is the auxiliary data
*/
static
enum fscache_checkaux nfs_fscache_inode_check_aux(void *cookie_netfs_data,
const void *data,
uint16_t datalen,
loff_t object_size)
{
struct nfs_fscache_inode_auxdata auxdata;
struct nfs_inode *nfsi = cookie_netfs_data;
if (datalen != sizeof(auxdata))
return FSCACHE_CHECKAUX_OBSOLETE;
memset(&auxdata, 0, sizeof(auxdata));
auxdata.mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec;
auxdata.mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec;
auxdata.ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec;
auxdata.ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec;
if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
auxdata.change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode);
if (memcmp(data, &auxdata, datalen) != 0)
return FSCACHE_CHECKAUX_OBSOLETE;
return FSCACHE_CHECKAUX_OKAY;
}
/*
* Get an extra reference on a read context.
* - This function can be absent if the completion function doesn't require a
* context.
* - The read context is passed back to NFS in the event that a data read on the
* cache fails with EIO - in which case the server must be contacted to
* retrieve the data, which requires the read context for security.
*/
static void nfs_fh_get_context(void *cookie_netfs_data, void *context)
{
get_nfs_open_context(context);
}
/*
* Release an extra reference on a read context.
* - This function can be absent if the completion function doesn't require a
* context.
*/
static void nfs_fh_put_context(void *cookie_netfs_data, void *context)
{
if (context)
put_nfs_open_context(context);
}
/*
* Define the inode object for FS-Cache. This is used to describe an inode
* object to fscache_acquire_cookie(). It is keyed by the NFS file handle for
* an inode.
*
* Coherency is managed by comparing the copies of i_size, i_mtime and i_ctime
* held in the cache auxiliary data for the data storage object with those in
* the inode struct in memory.
*/
const struct fscache_cookie_def nfs_fscache_inode_object_def = {
.name = "NFS.fh",
.type = FSCACHE_COOKIE_TYPE_DATAFILE,
.check_aux = nfs_fscache_inode_check_aux,
.get_context = nfs_fh_get_context,
.put_context = nfs_fh_put_context,
};
This diff is collapsed.
...@@ -12,46 +12,10 @@ ...@@ -12,46 +12,10 @@
#include <linux/nfs_mount.h> #include <linux/nfs_mount.h>
#include <linux/nfs4_mount.h> #include <linux/nfs4_mount.h>
#include <linux/fscache.h> #include <linux/fscache.h>
#include <linux/iversion.h>
#ifdef CONFIG_NFS_FSCACHE #ifdef CONFIG_NFS_FSCACHE
/*
* set of NFS FS-Cache objects that form a superblock key
*/
struct nfs_fscache_key {
struct rb_node node;
struct nfs_client *nfs_client; /* the server */
/* the elements of the unique key - as used by nfs_compare_super() and
* nfs_compare_mount_options() to distinguish superblocks */
struct {
struct {
unsigned long s_flags; /* various flags
* (& NFS_MS_MASK) */
} super;
struct {
struct nfs_fsid fsid;
int flags;
unsigned int rsize; /* read size */
unsigned int wsize; /* write size */
unsigned int acregmin; /* attr cache timeouts */
unsigned int acregmax;
unsigned int acdirmin;
unsigned int acdirmax;
} nfs_server;
struct {
rpc_authflavor_t au_flavor;
} rpc_auth;
/* uniquifier - can be used if nfs_server.flags includes
* NFS_MOUNT_UNSHARED */
u8 uniq_len;
char uniquifier[0];
} key;
};
/* /*
* Definition of the auxiliary data attached to NFS inode storage objects * Definition of the auxiliary data attached to NFS inode storage objects
* within the cache. * within the cache.
...@@ -69,32 +33,18 @@ struct nfs_fscache_inode_auxdata { ...@@ -69,32 +33,18 @@ struct nfs_fscache_inode_auxdata {
u64 change_attr; u64 change_attr;
}; };
/*
* fscache-index.c
*/
extern struct fscache_netfs nfs_fscache_netfs;
extern const struct fscache_cookie_def nfs_fscache_server_index_def;
extern const struct fscache_cookie_def nfs_fscache_super_index_def;
extern const struct fscache_cookie_def nfs_fscache_inode_object_def;
extern int nfs_fscache_register(void);
extern void nfs_fscache_unregister(void);
/* /*
* fscache.c * fscache.c
*/ */
extern void nfs_fscache_get_client_cookie(struct nfs_client *); extern int nfs_fscache_get_super_cookie(struct super_block *, const char *, int);
extern void nfs_fscache_release_client_cookie(struct nfs_client *);
extern void nfs_fscache_get_super_cookie(struct super_block *, const char *, int);
extern void nfs_fscache_release_super_cookie(struct super_block *); extern void nfs_fscache_release_super_cookie(struct super_block *);
extern void nfs_fscache_init_inode(struct inode *); extern void nfs_fscache_init_inode(struct inode *);
extern void nfs_fscache_clear_inode(struct inode *); extern void nfs_fscache_clear_inode(struct inode *);
extern void nfs_fscache_open_file(struct inode *, struct file *); extern void nfs_fscache_open_file(struct inode *, struct file *);
extern void nfs_fscache_release_file(struct inode *, struct file *);
extern void __nfs_fscache_invalidate_page(struct page *, struct inode *); 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 nfs_open_context *, extern int __nfs_readpage_from_fscache(struct nfs_open_context *,
struct inode *, struct page *); struct inode *, struct page *);
...@@ -103,25 +53,17 @@ extern int __nfs_readpages_from_fscache(struct nfs_open_context *, ...@@ -103,25 +53,17 @@ extern int __nfs_readpages_from_fscache(struct nfs_open_context *,
struct list_head *, unsigned *); struct list_head *, unsigned *);
extern void __nfs_readpage_to_fscache(struct inode *, struct page *, int); extern void __nfs_readpage_to_fscache(struct inode *, struct page *, int);
/* static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp)
* wait for a page to complete writing to the cache
*/
static inline void nfs_fscache_wait_on_page_write(struct nfs_inode *nfsi,
struct page *page)
{
if (PageFsCache(page))
fscache_wait_on_page_write(nfsi->fscache, page);
}
/*
* release the caching state associated with a page if undergoing complete page
* invalidation
*/
static inline void nfs_fscache_invalidate_page(struct page *page,
struct inode *inode)
{ {
if (PageFsCache(page)) if (PageFsCache(page)) {
__nfs_fscache_invalidate_page(page, inode); if (!gfpflags_allow_blocking(gfp) || !(gfp & __GFP_FS))
return false;
wait_on_page_fscache(page);
fscache_note_page_release(nfs_i_fscache(page->mapping->host));
nfs_inc_fscache_stats(page->mapping->host,
NFSIOS_FSCACHE_PAGES_UNCACHED);
}
return true;
} }
/* /*
...@@ -163,20 +105,32 @@ static inline void nfs_readpage_to_fscache(struct inode *inode, ...@@ -163,20 +105,32 @@ static inline void nfs_readpage_to_fscache(struct inode *inode,
__nfs_readpage_to_fscache(inode, page, sync); __nfs_readpage_to_fscache(inode, page, sync);
} }
/* static inline void nfs_fscache_update_auxdata(struct nfs_fscache_inode_auxdata *auxdata,
* Invalidate the contents of fscache for this inode. This will not sleep. struct nfs_inode *nfsi)
*/
static inline void nfs_fscache_invalidate(struct inode *inode)
{ {
fscache_invalidate(NFS_I(inode)->fscache); memset(auxdata, 0, sizeof(*auxdata));
auxdata->mtime_sec = nfsi->vfs_inode.i_mtime.tv_sec;
auxdata->mtime_nsec = nfsi->vfs_inode.i_mtime.tv_nsec;
auxdata->ctime_sec = nfsi->vfs_inode.i_ctime.tv_sec;
auxdata->ctime_nsec = nfsi->vfs_inode.i_ctime.tv_nsec;
if (NFS_SERVER(&nfsi->vfs_inode)->nfs_client->rpc_ops->version == 4)
auxdata->change_attr = inode_peek_iversion_raw(&nfsi->vfs_inode);
} }
/* /*
* Wait for an object to finish being invalidated. * Invalidate the contents of fscache for this inode. This will not sleep.
*/ */
static inline void nfs_fscache_wait_on_invalidate(struct inode *inode) static inline void nfs_fscache_invalidate(struct inode *inode, int flags)
{ {
fscache_wait_on_invalidate(NFS_I(inode)->fscache); struct nfs_fscache_inode_auxdata auxdata;
struct nfs_inode *nfsi = NFS_I(inode);
if (nfsi->fscache) {
nfs_fscache_update_auxdata(&auxdata, nfsi);
fscache_invalidate(nfsi->fscache, &auxdata,
i_size_read(&nfsi->vfs_inode), flags);
}
} }
/* /*
...@@ -190,28 +144,18 @@ static inline const char *nfs_server_fscache_state(struct nfs_server *server) ...@@ -190,28 +144,18 @@ static inline const char *nfs_server_fscache_state(struct nfs_server *server)
} }
#else /* CONFIG_NFS_FSCACHE */ #else /* CONFIG_NFS_FSCACHE */
static inline int nfs_fscache_register(void) { return 0; }
static inline void nfs_fscache_unregister(void) {}
static inline void nfs_fscache_get_client_cookie(struct nfs_client *clp) {}
static inline void nfs_fscache_release_client_cookie(struct nfs_client *clp) {}
static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {} static inline void nfs_fscache_release_super_cookie(struct super_block *sb) {}
static inline void nfs_fscache_init_inode(struct inode *inode) {} static inline void nfs_fscache_init_inode(struct inode *inode) {}
static inline void nfs_fscache_clear_inode(struct inode *inode) {} static inline void nfs_fscache_clear_inode(struct inode *inode) {}
static inline void nfs_fscache_open_file(struct inode *inode, static inline void nfs_fscache_open_file(struct inode *inode,
struct file *filp) {} struct file *filp) {}
static inline void nfs_fscache_release_file(struct inode *inode, struct file *file) {}
static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp) static inline int nfs_fscache_release_page(struct page *page, gfp_t gfp)
{ {
return 1; /* True: may release page */ 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,
struct page *page) {}
static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx, static inline int nfs_readpage_from_fscache(struct nfs_open_context *ctx,
struct inode *inode, struct inode *inode,
struct page *page) struct page *page)
...@@ -230,8 +174,7 @@ static inline void nfs_readpage_to_fscache(struct inode *inode, ...@@ -230,8 +174,7 @@ static inline void nfs_readpage_to_fscache(struct inode *inode,
struct page *page, int sync) {} struct page *page, int sync) {}
static inline void nfs_fscache_invalidate(struct inode *inode) {} static inline void nfs_fscache_invalidate(struct inode *inode, int flags) {}
static inline void nfs_fscache_wait_on_invalidate(struct inode *inode) {}
static inline const char *nfs_server_fscache_state(struct nfs_server *server) static inline const char *nfs_server_fscache_state(struct nfs_server *server)
{ {
......
...@@ -209,7 +209,7 @@ void nfs_set_cache_invalid(struct inode *inode, unsigned long flags) ...@@ -209,7 +209,7 @@ void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
if (!nfs_has_xattr_cache(nfsi)) if (!nfs_has_xattr_cache(nfsi))
flags &= ~NFS_INO_INVALID_XATTR; flags &= ~NFS_INO_INVALID_XATTR;
if (flags & NFS_INO_INVALID_DATA) if (flags & NFS_INO_INVALID_DATA)
nfs_fscache_invalidate(inode); nfs_fscache_invalidate(inode, 0);
flags &= ~(NFS_INO_REVAL_PAGECACHE | NFS_INO_REVAL_FORCED); flags &= ~(NFS_INO_REVAL_PAGECACHE | NFS_INO_REVAL_FORCED);
nfsi->cache_validity |= flags; nfsi->cache_validity |= flags;
...@@ -1289,6 +1289,7 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map ...@@ -1289,6 +1289,7 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
{ {
int ret; int ret;
nfs_fscache_invalidate(inode, 0);
if (mapping->nrpages != 0) { if (mapping->nrpages != 0) {
if (S_ISREG(inode->i_mode)) { if (S_ISREG(inode->i_mode)) {
ret = nfs_sync_mapping(mapping); ret = nfs_sync_mapping(mapping);
...@@ -1300,7 +1301,6 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map ...@@ -1300,7 +1301,6 @@ static int nfs_invalidate_mapping(struct inode *inode, struct address_space *map
return ret; return ret;
} }
nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE);
nfs_fscache_wait_on_invalidate(inode);
dfprintk(PAGECACHE, "NFS: (%s/%Lu) data cache invalidated\n", dfprintk(PAGECACHE, "NFS: (%s/%Lu) data cache invalidated\n",
inode->i_sb->s_id, inode->i_sb->s_id,
...@@ -2374,10 +2374,6 @@ static int __init init_nfs_fs(void) ...@@ -2374,10 +2374,6 @@ static int __init init_nfs_fs(void)
if (err < 0) if (err < 0)
goto out9; goto out9;
err = nfs_fscache_register();
if (err < 0)
goto out8;
err = nfsiod_start(); err = nfsiod_start();
if (err) if (err)
goto out7; goto out7;
...@@ -2429,8 +2425,6 @@ static int __init init_nfs_fs(void) ...@@ -2429,8 +2425,6 @@ static int __init init_nfs_fs(void)
out6: out6:
nfsiod_stop(); nfsiod_stop();
out7: out7:
nfs_fscache_unregister();
out8:
unregister_pernet_subsys(&nfs_net_ops); unregister_pernet_subsys(&nfs_net_ops);
out9: out9:
nfs_sysfs_exit(); nfs_sysfs_exit();
...@@ -2445,7 +2439,6 @@ static void __exit exit_nfs_fs(void) ...@@ -2445,7 +2439,6 @@ static void __exit exit_nfs_fs(void)
nfs_destroy_readpagecache(); nfs_destroy_readpagecache();
nfs_destroy_inodecache(); nfs_destroy_inodecache();
nfs_destroy_nfspagecache(); nfs_destroy_nfspagecache();
nfs_fscache_unregister();
unregister_pernet_subsys(&nfs_net_ops); unregister_pernet_subsys(&nfs_net_ops);
rpc_proc_unregister(&init_net, "nfs"); rpc_proc_unregister(&init_net, "nfs");
unregister_nfs_fs(); unregister_nfs_fs();
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
{ BIT(NFS_INO_ACL_LRU_SET), "ACL_LRU_SET" }, \ { BIT(NFS_INO_ACL_LRU_SET), "ACL_LRU_SET" }, \
{ BIT(NFS_INO_INVALIDATING), "INVALIDATING" }, \ { BIT(NFS_INO_INVALIDATING), "INVALIDATING" }, \
{ BIT(NFS_INO_FSCACHE), "FSCACHE" }, \ { BIT(NFS_INO_FSCACHE), "FSCACHE" }, \
{ BIT(NFS_INO_FSCACHE_LOCK), "FSCACHE_LOCK" }, \
{ BIT(NFS_INO_LAYOUTCOMMIT), "NEED_LAYOUTCOMMIT" }, \ { BIT(NFS_INO_LAYOUTCOMMIT), "NEED_LAYOUTCOMMIT" }, \
{ BIT(NFS_INO_LAYOUTCOMMITTING), "LAYOUTCOMMIT" }, \ { BIT(NFS_INO_LAYOUTCOMMITTING), "LAYOUTCOMMIT" }, \
{ BIT(NFS_INO_LAYOUTSTATS), "LAYOUTSTATS" }, \ { BIT(NFS_INO_LAYOUTSTATS), "LAYOUTSTATS" }, \
......
...@@ -1204,42 +1204,42 @@ static int nfs_compare_super(struct super_block *sb, struct fs_context *fc) ...@@ -1204,42 +1204,42 @@ static int nfs_compare_super(struct super_block *sb, struct fs_context *fc)
} }
#ifdef CONFIG_NFS_FSCACHE #ifdef CONFIG_NFS_FSCACHE
static void nfs_get_cache_cookie(struct super_block *sb, static int nfs_get_cache_cookie(struct super_block *sb,
struct nfs_fs_context *ctx) struct nfs_fs_context *ctx)
{ {
struct nfs_server *nfss = NFS_SB(sb); struct nfs_server *nfss = NFS_SB(sb);
char *uniq = NULL; char *uniq = NULL;
int ulen = 0; int ulen = 0;
nfss->fscache_key = NULL;
nfss->fscache = NULL; nfss->fscache = NULL;
if (!ctx) if (!ctx)
return; return 0;
if (ctx->clone_data.sb) { if (ctx->clone_data.sb) {
struct nfs_server *mnt_s = NFS_SB(ctx->clone_data.sb); struct nfs_server *mnt_s = NFS_SB(ctx->clone_data.sb);
if (!(mnt_s->options & NFS_OPTION_FSCACHE)) if (!(mnt_s->options & NFS_OPTION_FSCACHE))
return; return 0;
if (mnt_s->fscache_key) { if (mnt_s->fscache_uniq) {
uniq = mnt_s->fscache_key->key.uniquifier; uniq = mnt_s->fscache_uniq;
ulen = mnt_s->fscache_key->key.uniq_len; ulen = strlen(uniq);
} }
} else { } else {
if (!(ctx->options & NFS_OPTION_FSCACHE)) if (!(ctx->options & NFS_OPTION_FSCACHE))
return; return 0;
if (ctx->fscache_uniq) { if (ctx->fscache_uniq) {
uniq = ctx->fscache_uniq; uniq = ctx->fscache_uniq;
ulen = strlen(ctx->fscache_uniq); ulen = strlen(ctx->fscache_uniq);
} }
} }
nfs_fscache_get_super_cookie(sb, uniq, ulen); return nfs_fscache_get_super_cookie(sb, uniq, ulen);
} }
#else #else
static void nfs_get_cache_cookie(struct super_block *sb, static int nfs_get_cache_cookie(struct super_block *sb,
struct nfs_fs_context *ctx) struct nfs_fs_context *ctx)
{ {
return 0;
} }
#endif #endif
...@@ -1299,7 +1299,9 @@ int nfs_get_tree_common(struct fs_context *fc) ...@@ -1299,7 +1299,9 @@ int nfs_get_tree_common(struct fs_context *fc)
s->s_blocksize_bits = bsize; s->s_blocksize_bits = bsize;
s->s_blocksize = 1U << bsize; s->s_blocksize = 1U << bsize;
} }
nfs_get_cache_cookie(s, ctx); error = nfs_get_cache_cookie(s, ctx);
if (error < 0)
goto error_splat_super;
} }
error = nfs_get_root(s, fc); error = nfs_get_root(s, fc);
......
...@@ -294,6 +294,7 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c ...@@ -294,6 +294,7 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c
nfs_inc_stats(inode, NFSIOS_EXTENDWRITE); nfs_inc_stats(inode, NFSIOS_EXTENDWRITE);
out: out:
spin_unlock(&inode->i_lock); spin_unlock(&inode->i_lock);
nfs_fscache_invalidate(inode, 0);
} }
/* A writeback failed: mark the page as bad, and invalidate the page cache */ /* A writeback failed: mark the page as bad, and invalidate the page cache */
......
...@@ -275,7 +275,6 @@ struct nfs4_copy_state { ...@@ -275,7 +275,6 @@ struct nfs4_copy_state {
#define NFS_INO_ACL_LRU_SET (2) /* Inode is on the LRU list */ #define NFS_INO_ACL_LRU_SET (2) /* Inode is on the LRU list */
#define NFS_INO_INVALIDATING (3) /* inode is being invalidated */ #define NFS_INO_INVALIDATING (3) /* inode is being invalidated */
#define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */ #define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */
#define NFS_INO_FSCACHE_LOCK (6) /* FS-Cache cookie management lock */
#define NFS_INO_FORCE_READDIR (7) /* force readdirplus */ #define NFS_INO_FORCE_READDIR (7) /* force readdirplus */
#define NFS_INO_LAYOUTCOMMIT (9) /* layoutcommit required */ #define NFS_INO_LAYOUTCOMMIT (9) /* layoutcommit required */
#define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */ #define NFS_INO_LAYOUTCOMMITTING (10) /* layoutcommit inflight */
......
...@@ -120,11 +120,6 @@ struct nfs_client { ...@@ -120,11 +120,6 @@ struct nfs_client {
* This is used to generate the mv0 callback address. * This is used to generate the mv0 callback address.
*/ */
char cl_ipaddr[48]; char cl_ipaddr[48];
#ifdef CONFIG_NFS_FSCACHE
struct fscache_cookie *fscache; /* client index cache cookie */
#endif
struct net *cl_net; struct net *cl_net;
struct list_head pending_cb_stateids; struct list_head pending_cb_stateids;
}; };
...@@ -194,8 +189,8 @@ struct nfs_server { ...@@ -194,8 +189,8 @@ struct nfs_server {
struct nfs_auth_info auth_info; /* parsed auth flavors */ struct nfs_auth_info auth_info; /* parsed auth flavors */
#ifdef CONFIG_NFS_FSCACHE #ifdef CONFIG_NFS_FSCACHE
struct nfs_fscache_key *fscache_key; /* unique key for superblock */ struct fscache_volume *fscache; /* superblock cookie */
struct fscache_cookie *fscache; /* superblock cookie */ char *fscache_uniq; /* Uniquifier (or NULL) */
#endif #endif
u32 pnfs_blksize; /* layout_blksize attr */ u32 pnfs_blksize; /* layout_blksize attr */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment