]> git.itanic.dy.fi Git - linux-stable/commitdiff
NFS: Fix fscache super_cookie index_key from changing after umount
authorDave Wysochanski <dwysocha@redhat.com>
Wed, 15 Apr 2020 20:14:41 +0000 (16:14 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 May 2020 06:20:22 +0000 (08:20 +0200)
[ Upstream commit d9bfced1fbcb35b28d8fbed4e785d2807055ed2b ]

Commit 402cb8dda949 ("fscache: Attach the index key and aux data to
the cookie") added the index_key and index_key_len parameters to
fscache_acquire_cookie(), and updated the callers in the NFS client.
One of the callers was inside nfs_fscache_get_super_cookie()
and was changed to use the full struct nfs_fscache_key as the
index_key.  However, a couple members of this structure contain
pointers and thus will change each time the same NFS share is
remounted.  Since index_key is used for fscache_cookie->key_hash
and this subsequently is used to compare cookies, the effectiveness
of fscache with NFS is reduced to the point at which a umount
occurs.   Any subsequent remount of the same share will cause a
unique NFS super_block index_key and key_hash to be generated for
the same data, rendering any prior fscache data unable to be
found.  A simple reproducer demonstrates the problem.

1. Mount share with 'fsc', create a file, drop page cache
systemctl start cachefilesd
mount -o vers=3,fsc 127.0.0.1:/export /mnt
dd if=/dev/zero of=/mnt/file1.bin bs=4096 count=1
echo 3 > /proc/sys/vm/drop_caches

2. Read file into page cache and fscache, then unmount
dd if=/mnt/file1.bin of=/dev/null bs=4096 count=1
umount /mnt

3. Remount and re-read which should come from fscache
mount -o vers=3,fsc 127.0.0.1:/export /mnt
echo 3 > /proc/sys/vm/drop_caches
dd if=/mnt/file1.bin of=/dev/null bs=4096 count=1

4. Check for READ ops in mountstats - there should be none
grep READ: /proc/self/mountstats

Looking at the history and the removed function, nfs_super_get_key(),
we should only use nfs_fscache_key.key plus any uniquifier, for
the fscache index_key.

Fixes: 402cb8dda949 ("fscache: Attach the index key and aux data to the cookie")
Signed-off-by: Dave Wysochanski <dwysocha@redhat.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/nfs/fscache.c

index a6dcc2151e779aae7ef4916955d8e59727a5d383..3184063322d481be8ac3441cc37bff012889a69d 100644 (file)
@@ -188,7 +188,8 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int
        /* create a cache index for looking up filehandles */
        nfss->fscache = fscache_acquire_cookie(nfss->nfs_client->fscache,
                                               &nfs_fscache_super_index_def,
-                                              key, sizeof(*key) + ulen,
+                                              &key->key,
+                                              sizeof(key->key) + ulen,
                                               NULL, 0,
                                               nfss, 0, true);
        dfprintk(FSCACHE, "NFS: get superblock cookie (0x%p/0x%p)\n",