mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
fusefs: don't require FUSE_EXPORT_SUPPORT for async invalidation
In r348560 I thought that FUSE_EXPORT_SUPPORT was required for cases where the node to be invalidated (or the parent of the entry to be invalidated) wasn't cached. But I realize now that that's not the case. During entry invalidation, if the parent isn't in the vfs hash table, then it must've been reclaimed. And since fuse_vnop_reclaim does a cache_purge, that means the entry to be invalidated has already been removed from the namecache. And during inode invalidation, if the inode to be invalidated isn't in the vfs hash table, then it too must've been reclaimed. In that case it will have no buffer cache to invalidate. Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
eae1ae132c
commit
6ff7f297f8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/fuse2/; revision=348582
@ -364,31 +364,17 @@ fuse_internal_fsync(struct vnode *vp,
|
||||
}
|
||||
|
||||
/* Asynchronous invalidation */
|
||||
SDT_PROBE_DEFINE1(fusefs, , internal, invalidate_without_export,
|
||||
"struct mount*");
|
||||
SDT_PROBE_DEFINE2(fusefs, , internal, invalidate_cache_hit,
|
||||
"struct vnode*", "struct vnode*");
|
||||
int
|
||||
fuse_internal_invalidate_entry(struct mount *mp, struct uio *uio)
|
||||
{
|
||||
struct fuse_notify_inval_entry_out fnieo;
|
||||
struct fuse_data *data = fuse_get_mpdata(mp);
|
||||
struct componentname cn;
|
||||
struct vnode *dvp, *vp;
|
||||
char name[PATH_MAX];
|
||||
int err;
|
||||
|
||||
if (!(data->dataflags & FSESS_EXPORT_SUPPORT)) {
|
||||
/*
|
||||
* Linux allows file systems without export support to use
|
||||
* asynchronous notification because its inode cache is indexed
|
||||
* purely by the inode number. But FreeBSD's vnode is cache
|
||||
* requires access to the entire vnode structure.
|
||||
*/
|
||||
SDT_PROBE1(fusefs, , internal, invalidate_without_export, mp);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if ((err = uiomove(&fnieo, sizeof(fnieo), uio)) != 0)
|
||||
return (err);
|
||||
|
||||
@ -405,6 +391,11 @@ fuse_internal_invalidate_entry(struct mount *mp, struct uio *uio)
|
||||
else
|
||||
err = fuse_internal_get_cached_vnode( mp, fnieo.parent,
|
||||
LK_SHARED, &dvp);
|
||||
/*
|
||||
* If dvp is not in the cache, then it must've been reclaimed. And
|
||||
* since fuse_vnop_reclaim does a cache_purge, name's entry must've
|
||||
* been invalidated already. So we can safely return if dvp == NULL
|
||||
*/
|
||||
if (err != 0 || dvp == NULL)
|
||||
return (err);
|
||||
/*
|
||||
@ -432,21 +423,9 @@ int
|
||||
fuse_internal_invalidate_inode(struct mount *mp, struct uio *uio)
|
||||
{
|
||||
struct fuse_notify_inval_inode_out fniio;
|
||||
struct fuse_data *data = fuse_get_mpdata(mp);
|
||||
struct vnode *vp;
|
||||
int err;
|
||||
|
||||
if (!(data->dataflags & FSESS_EXPORT_SUPPORT)) {
|
||||
/*
|
||||
* Linux allows file systems without export support to use
|
||||
* asynchronous notification because its inode cache is indexed
|
||||
* purely by the inode number. But FreeBSD's vnode is cache
|
||||
* requires access to the entire vnode structure.
|
||||
*/
|
||||
SDT_PROBE1(fusefs, , internal, invalidate_without_export, mp);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
if ((err = uiomove(&fniio, sizeof(fniio), uio)) != 0)
|
||||
return (err);
|
||||
|
||||
|
@ -519,9 +519,12 @@ fuse_vfsop_unmount(struct mount *mp, int mntflags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDT_PROBE_DEFINE1(fusefs, , vfsops, invalidate_without_export,
|
||||
"struct mount*");
|
||||
static int
|
||||
fuse_vfsop_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
|
||||
{
|
||||
struct fuse_data *data = fuse_get_mpdata(mp);
|
||||
uint64_t nodeid = ino;
|
||||
struct thread *td = curthread;
|
||||
struct fuse_dispatcher fdi;
|
||||
@ -532,6 +535,15 @@ fuse_vfsop_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp)
|
||||
enum vtype vtyp;
|
||||
int error;
|
||||
|
||||
if (!(data->dataflags & FSESS_EXPORT_SUPPORT)) {
|
||||
/*
|
||||
* Unreachable unless you do something stupid, like export a
|
||||
* nullfs mount of a fusefs file system.
|
||||
*/
|
||||
SDT_PROBE1(fusefs, , vfsops, invalidate_without_export, mp);
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
error = fuse_internal_get_cached_vnode(mp, ino, flags, vpp);
|
||||
if (error || *vpp != NULL)
|
||||
return error;
|
||||
|
@ -50,11 +50,6 @@ using namespace testing;
|
||||
|
||||
class Notify: public FuseTest {
|
||||
public:
|
||||
virtual void SetUp() {
|
||||
m_init_flags = FUSE_EXPORT_SUPPORT;
|
||||
FuseTest::SetUp();
|
||||
}
|
||||
|
||||
void expect_lookup(uint64_t parent, const char *relpath, uint64_t ino,
|
||||
off_t size, Sequence &seq)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user