aboutsummaryrefslogtreecommitdiff
path: root/sys/fs/fuse/fuse_node.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/fs/fuse/fuse_node.c')
-rw-r--r--sys/fs/fuse/fuse_node.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/sys/fs/fuse/fuse_node.c b/sys/fs/fuse/fuse_node.c
index 777519450954..742dc66bcafc 100644
--- a/sys/fs/fuse/fuse_node.c
+++ b/sys/fs/fuse/fuse_node.c
@@ -297,6 +297,8 @@ fuse_vnode_get(struct mount *mp,
__enum_uint8(vtype) vtyp)
{
struct thread *td = curthread;
+ bool exportable = fuse_get_mpdata(mp)->dataflags & FSESS_EXPORT_SUPPORT;
+
/*
* feo should only be NULL for the root directory, which (when libfuse
* is used) always has generation 0
@@ -309,6 +311,23 @@ fuse_vnode_get(struct mount *mp,
"Assigned same inode to both parent and child.");
return EIO;
}
+ if (feo && feo->nodeid != feo->attr.ino && exportable) {
+ /*
+ * NFS servers (both kernelspace and userspace) rely on
+ * VFS_VGET to lookup inodes. But that's only possible if the
+ * file's inode number matches its nodeid, which isn't
+ * necessarily the case for FUSE. If they don't match, then we
+ * can complete the current operation, but future VFS_VGET
+ * operations will almost certainly return spurious results.
+ * Warn the operator.
+ *
+ * But only warn the operator if the file system reports
+ * NFS-compatibility, because that's the only time that this
+ * matters, and dumb fuse servers abound.
+ */
+ fuse_warn(fuse_get_mpdata(mp), FSESS_WARN_INODE_MISMATCH,
+ "file has different inode number and nodeid.");
+ }
err = fuse_vnode_alloc(mp, td, nodeid, vtyp, vpp);
if (err) {
@@ -354,7 +373,7 @@ void
fuse_vnode_open(struct vnode *vp, int32_t fuse_open_flags, struct thread *td)
{
if (vnode_vtype(vp) == VREG)
- vnode_create_vobject(vp, 0, td);
+ vnode_create_vobject(vp, VNODE_NO_SIZE, td);
}
int