diff options
Diffstat (limited to 'sys/fs/fuse/fuse_node.c')
-rw-r--r-- | sys/fs/fuse/fuse_node.c | 21 |
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 |