]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
NFS: Fix regression whereby fscache errors are appearing on 'nofsc' mounts
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Sat, 3 Aug 2019 17:39:24 +0000 (13:39 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Aug 2019 06:28:39 +0000 (08:28 +0200)
[ Upstream commit dea1bb35c5f35e0577cfc61f79261d80b8715221 ]

People are reporing seeing fscache errors being reported concerning
duplicate cookies even in cases where they are not setting up fscache
at all. The rule needs to be that if fscache is not enabled, then it
should have no side effects at all.

To ensure this is the case, we disable fscache completely on all superblocks
for which the 'fsc' mount option was not set. In order to avoid issues
with '-oremount', we also disable the ability to turn fscache on via
remount.

Fixes: f1fe29b4a02d ("NFS: Use i_writecount to control whether...")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=200145
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Cc: Steve Dickson <steved@redhat.com>
Cc: David Howells <dhowells@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfs/fscache.c
fs/nfs/fscache.h
fs/nfs/super.c

index 4dc887813c71d312fe09df36ddbbd78a0b27024a..a7bc4e0494f92f61ea7989310ffd8ae6ebadc21b 100644 (file)
@@ -118,6 +118,10 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int
        struct rb_node **p, *parent;
        int diff;
 
+       nfss->fscache_key = NULL;
+       nfss->fscache = NULL;
+       if (!(nfss->options & NFS_OPTION_FSCACHE))
+               return;
        if (!uniq) {
                uniq = "";
                ulen = 1;
@@ -230,10 +234,11 @@ void nfs_fscache_release_super_cookie(struct super_block *sb)
 void nfs_fscache_init_inode(struct inode *inode)
 {
        struct nfs_fscache_inode_auxdata auxdata;
+       struct nfs_server *nfss = NFS_SERVER(inode);
        struct nfs_inode *nfsi = NFS_I(inode);
 
        nfsi->fscache = NULL;
-       if (!S_ISREG(inode->i_mode))
+       if (!(nfss->fscache && S_ISREG(inode->i_mode)))
                return;
 
        memset(&auxdata, 0, sizeof(auxdata));
index 161ba2edb9d0410f7722cc4b7ba62f8d4614cc80..6363ea956858124a503a1ae8c14604dfd2726999 100644 (file)
@@ -186,7 +186,7 @@ static inline void nfs_fscache_wait_on_invalidate(struct inode *inode)
  */
 static inline const char *nfs_server_fscache_state(struct nfs_server *server)
 {
-       if (server->fscache && (server->options & NFS_OPTION_FSCACHE))
+       if (server->fscache)
                return "yes";
        return "no ";
 }
index 6df9b85caf20560b8bafd83777ccabb7ec2f8760..d90efdea9fbd6fba6058d38c1e6221368eac6007 100644 (file)
@@ -2239,6 +2239,7 @@ nfs_compare_remount_data(struct nfs_server *nfss,
            data->acdirmin != nfss->acdirmin / HZ ||
            data->acdirmax != nfss->acdirmax / HZ ||
            data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) ||
+           (data->options & NFS_OPTION_FSCACHE) != (nfss->options & NFS_OPTION_FSCACHE) ||
            data->nfs_server.port != nfss->port ||
            data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
            !rpc_cmp_addr((struct sockaddr *)&data->nfs_server.address,