diff --git a/sys/fs/fuse/fuse_internal.c b/sys/fs/fuse/fuse_internal.c index 6de36a3e492e..788543fc39b4 100644 --- a/sys/fs/fuse/fuse_internal.c +++ b/sys/fs/fuse/fuse_internal.c @@ -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); diff --git a/sys/fs/fuse/fuse_vfsops.c b/sys/fs/fuse/fuse_vfsops.c index 36382118ccd0..b059e65c7f57 100644 --- a/sys/fs/fuse/fuse_vfsops.c +++ b/sys/fs/fuse/fuse_vfsops.c @@ -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; diff --git a/tests/sys/fs/fusefs/notify.cc b/tests/sys/fs/fusefs/notify.cc index 9b702b37e8ad..da6417ed613f 100644 --- a/tests/sys/fs/fusefs/notify.cc +++ b/tests/sys/fs/fusefs/notify.cc @@ -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) {