@@ -2203,6 +2203,10 @@ static unsigned long nfs_access_max_cachesize = ULONG_MAX;
module_param(nfs_access_max_cachesize, ulong, 0644);
MODULE_PARM_DESC(nfs_access_max_cachesize, "NFS access maximum total cache length");
+static bool nfs_fasc = false;
+module_param(nfs_fasc, bool, 0644);
+MODULE_PARM_DESC(nfs_fasc, "Use file access stale cache for NFS");
+
static void nfs_access_free_entry(struct nfs_access_entry *entry)
{
put_cred(entry->cred);
@@ -2373,7 +2377,9 @@ static u64 nfs_access_login_time(const struct task_struct *task,
static int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, bool may_block)
{
struct nfs_inode *nfsi = NFS_I(inode);
- u64 login_time = nfs_access_login_time(current, cred);
+ u64 login_time;
+ if (nfs_fasc)
+ login_time = nfs_access_login_time(current, cred);
struct nfs_access_entry *cache;
bool retry = true;
int err;
@@ -2401,9 +2407,11 @@ static int nfs_access_get_cached(struct inode *inode, const struct cred *cred, s
spin_lock(&inode->i_lock);
retry = false;
}
- err = -ENOENT;
- if ((s64)(login_time - cache->timestamp) > 0)
- goto out;
+ if (nfs_fasc) {
+ err = -ENOENT;
+ if ((s64)(login_time - cache->timestamp) > 0)
+ goto out;
+ }
res->cred = cache->cred;
res->mask = cache->mask;
list_move_tail(&cache->lru, &nfsi->access_cache_entry_lru);
@@ -2423,7 +2431,9 @@ static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cre
* but do it without locking.
*/
struct nfs_inode *nfsi = NFS_I(inode);
- u64 login_time = nfs_access_login_time(current, cred);
+ u64 login_time;
+ if (nfs_fasc)
+ login_time = nfs_access_login_time(current, cred);
struct nfs_access_entry *cache;
int err = -ECHILD;
struct list_head *lh;
@@ -2438,8 +2448,10 @@ static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cre
cache = NULL;
if (cache == NULL)
goto out;
- if ((s64)(login_time - cache->timestamp) > 0)
- goto out;
+ if (nfs_fasc) {
+ if ((s64)(login_time - cache->timestamp) > 0)
+ goto out;
+ }
if (nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS))
goto out;
res->cred = cache->cred;
@@ -2493,7 +2505,8 @@ void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set)
RB_CLEAR_NODE(&cache->rb_node);
cache->cred = get_cred(set->cred);
cache->mask = set->mask;
- cache->timestamp = ktime_get_ns();
+ if (nfs_fasc)
+ cache->timestamp = ktime_get_ns();
/* The above field assignments must be visible
* before this item appears on the lru. We cannot easily
BugLink: https://bugs.launchpad.net/bugs/2022098 The file-access stale cache "refresh" behaviour introduced to fix https://bugs.launchpad.net/bugs/2003053 has caused a massive increase in NFS server queries in some cases - which effectively DoS's the NFS server and makes it unusable in some cases. This SAUCE patch makes the new behaviour optional using the "nfs_fasc=1" module parameter to nfs Suggested-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com> Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com> --- fs/nfs/dir.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)