mirror of https://github.com/torvalds/linux.git
Revert "fs/9p: Refresh metadata in d_revalidate for uncached mode too"
This reverts commit290434474c. That commit broke cache=mmap, a mode that doesn't cache metadata, but still has writeback cache. In commit290434474c("fs/9p: Refresh metadata in d_revalidate for uncached mode too") we considered metadata cache to be enough to not look at the server, but in writeback cache too looking at the server size would make the vfs consider the file has been truncated before the data has been flushed out, making the following repro fail (nothing is ever read back, the resulting file ends up with no data written) ``` #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> char buf[4096]; int main(int argc, char *argv[]) { int ret, i; int fdw, fdr; if (argc < 2) return 1; fdw = openat(AT_FDCWD, argv[1], O_RDWR|O_CREAT|O_EXCL|O_CLOEXEC, 0600); if (fdw < 0) { fprintf(stderr, "cannot open fdw\n"); return 1; } write(fdw, buf, sizeof(buf)); fdr = openat(AT_FDCWD, argv[1], O_RDONLY|O_CLOEXEC); if (fdr < 0) { fprintf(stderr, "cannot open fdr\n"); close(fdw); return 1; } for (i = 0; i < 10; i++) { ret = read(fdr, buf, sizeof(buf)); fprintf(stderr, "i: %d, read returns %d\n", i, ret); } close(fdr); close(fdw); return 0; } ``` There is a fix for this particular reproducer but it looks like there are other problems around metadata refresh (e.g. around file rename), so revert this to avoid d_revalidate in uncached mode for now. Reported-by: Song Liu <song@kernel.org> Link: https://lkml.kernel.org/r/CAHzjS_u_SYdt5=2gYO_dxzMKXzGMt-TfdE_ueowg-Hq5tRCAiw@mail.gmail.com Reported-by: Andrii Nakryiko <andrii.nakryiko@gmail.com> Link: https://lore.kernel.org/bpf/CAEf4BzZbCE4tLoDZyUf_aASpgAGFj75QMfSXX4a4dLYixnOiLg@mail.gmail.com/ Fixes:290434474c("fs/9p: Refresh metadata in d_revalidate for uncached mode too") Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
This commit is contained in:
parent
211ddde082
commit
43c36a56cc
|
|
@ -66,7 +66,6 @@ static int __v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
|
|||
struct p9_fid *fid;
|
||||
struct inode *inode;
|
||||
struct v9fs_inode *v9inode;
|
||||
unsigned int cached;
|
||||
|
||||
if (flags & LOOKUP_RCU)
|
||||
return -ECHILD;
|
||||
|
|
@ -76,11 +75,7 @@ static int __v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
|
|||
goto out_valid;
|
||||
|
||||
v9inode = V9FS_I(inode);
|
||||
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
|
||||
|
||||
cached = v9ses->cache & (CACHE_META | CACHE_LOOSE);
|
||||
|
||||
if (!cached || v9inode->cache_validity & V9FS_INO_INVALID_ATTR) {
|
||||
if (v9inode->cache_validity & V9FS_INO_INVALID_ATTR) {
|
||||
int retval;
|
||||
struct v9fs_session_info *v9ses;
|
||||
|
||||
|
|
@ -114,6 +109,7 @@ static int __v9fs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
|
|||
p9_debug(P9_DEBUG_VFS,
|
||||
"refresh inode: dentry = %pd (%p), got error %pe\n",
|
||||
dentry, dentry, ERR_PTR(retval));
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
|
@ -150,8 +146,6 @@ const struct dentry_operations v9fs_cached_dentry_operations = {
|
|||
};
|
||||
|
||||
const struct dentry_operations v9fs_dentry_operations = {
|
||||
.d_revalidate = v9fs_lookup_revalidate,
|
||||
.d_weak_revalidate = __v9fs_lookup_revalidate,
|
||||
.d_release = v9fs_dentry_release,
|
||||
.d_unalias_trylock = v9fs_dentry_unalias_trylock,
|
||||
.d_unalias_unlock = v9fs_dentry_unalias_unlock,
|
||||
|
|
|
|||
|
|
@ -1339,14 +1339,8 @@ int v9fs_refresh_inode(struct p9_fid *fid, struct inode *inode)
|
|||
* Don't update inode if the file type is different
|
||||
*/
|
||||
umode = p9mode2unixmode(v9ses, st, &rdev);
|
||||
if (inode_wrong_type(inode, umode)) {
|
||||
/*
|
||||
* Do this as a way of letting the caller know the inode should not
|
||||
* be reused
|
||||
*/
|
||||
v9fs_invalidate_inode_attr(inode);
|
||||
if (inode_wrong_type(inode, umode))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't want to refresh inode->i_size,
|
||||
|
|
|
|||
|
|
@ -897,14 +897,8 @@ int v9fs_refresh_inode_dotl(struct p9_fid *fid, struct inode *inode)
|
|||
/*
|
||||
* Don't update inode if the file type is different
|
||||
*/
|
||||
if (inode_wrong_type(inode, st->st_mode)) {
|
||||
/*
|
||||
* Do this as a way of letting the caller know the inode should not
|
||||
* be reused
|
||||
*/
|
||||
v9fs_invalidate_inode_attr(inode);
|
||||
if (inode_wrong_type(inode, st->st_mode))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't want to refresh inode->i_size,
|
||||
|
|
|
|||
Loading…
Reference in New Issue