2022-05-04 19:55:05

by David Wysochanski

[permalink] [raw]
Subject: [PATCH] NFS: Pass i_size to fscache_unuse_cookie() when a file is released

Pass updated i_size in fscache_unuse_cookie() when called
from nfs_fscache_release_file(), which ensures the size of
an fscache object gets written to the cache storage. Failing
to do so results in unnessary reads from the NFS server, even
when the data is cached, due to a cachefiles object coherency
check failing with a trace similar to the following:
cachefiles_coherency: o=0000000e BAD osiz B=afbb3 c=0

This problem can be reproduced as follows:
#!/bin/bash
v=4.2; NFS_SERVER=127.0.0.1
set -e; trap cleanup EXIT; rc=1
function cleanup {
umount /mnt/nfs > /dev/null 2>&1
RC_STR="TEST PASS"
[ $rc -eq 1 ] && RC_STR="TEST FAIL"
echo "$RC_STR on $(uname -r) with NFSv$v and server $NFS_SERVER"
}
mount -o vers=$v,fsc $NFS_SERVER:/export /mnt/nfs
rm -f /mnt/nfs/file1.bin > /dev/null 2>&1
dd if=/dev/zero of=/mnt/nfs/file1.bin bs=4096 count=1 > /dev/null 2>&1
echo 3 > /proc/sys/vm/drop_caches
echo Read file 1st time from NFS server into fscache
dd if=/mnt/nfs/file1.bin of=/dev/null > /dev/null 2>&1
umount /mnt/nfs && mount -o vers=$v,fsc $NFS_SERVER:/export /mnt/nfs
echo 3 > /proc/sys/vm/drop_caches
echo Read file 2nd time from fscache
dd if=/mnt/nfs/file1.bin of=/dev/null > /dev/null 2>&1
echo Check mountstats for NFS read
grep -q "READ: 0" /proc/self/mountstats # (1st number) == 0
[ $? -eq 0 ] && rc=0

Fixes: a6b5a28eb56c "nfs: Convert to new fscache volume/cookie API"
Signed-off-by: Dave Wysochanski <[email protected]>
---
fs/nfs/fscache.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c
index f73c09a9cf0a..e861d7bae305 100644
--- a/fs/nfs/fscache.c
+++ b/fs/nfs/fscache.c
@@ -231,11 +231,10 @@ void nfs_fscache_release_file(struct inode *inode, struct file *filp)
{
struct nfs_fscache_inode_auxdata auxdata;
struct fscache_cookie *cookie = nfs_i_fscache(inode);
+ loff_t i_size = i_size_read(inode);

- if (fscache_cookie_valid(cookie)) {
- nfs_fscache_update_auxdata(&auxdata, inode);
- fscache_unuse_cookie(cookie, &auxdata, NULL);
- }
+ nfs_fscache_update_auxdata(&auxdata, inode);
+ fscache_unuse_cookie(cookie, &auxdata, &i_size);
}

/*
--
2.27.1



2022-05-06 10:17:06

by Daire Byrne

[permalink] [raw]
Subject: Re: [PATCH] NFS: Pass i_size to fscache_unuse_cookie() when a file is released

On Wed, 4 May 2022 at 14:22, Dave Wysochanski <[email protected]> wrote:
>
> Pass updated i_size in fscache_unuse_cookie() when called
> from nfs_fscache_release_file(), which ensures the size of
> an fscache object gets written to the cache storage. Failing
> to do so results in unnessary reads from the NFS server, even
> when the data is cached, due to a cachefiles object coherency
> check failing with a trace similar to the following:
> cachefiles_coherency: o=0000000e BAD osiz B=afbb3 c=0

I can confirm that this fixes an oddity I had noticed with the "new" fscache.

When running an fio read benchmark, if you remounted or dropped caches
between reads, it seemed like it required two initial reads of the
data (and writes to cache) before all subsequent reads would come from
the fscache disk.

Tested-by: Daire Byrne <[email protected]>

Cheers,

Daire