diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index dd7cf0012fbe..4fcf9e8be418 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -204,8 +204,23 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, * allowed without an explicit export of the new * directory. */ - if (err == -ENOENT && !(exp->ex_flags & NFSEXP_V4ROOT)) - err = 0; + if (err == -ENOENT && !(exp->ex_flags & NFSEXP_V4ROOT)) { +#ifdef CONFIG_TRUENAS + /* + * For ZFS snapshot entries under a zfs_snapdir + * export, the fallback dentry is an automount + * stub with simple_dir_operations that returns + * empty READDIR (NFS4_OK, zero entries). The + * client caches this silently with no error + * signal to trigger re-resolution. Return ESTALE + * so the client retries via LOOKUP. + */ + if (is_snapdir) + err = -ESTALE; + else +#endif /* CONFIG_TRUENAS */ + err = 0; + } path_put(&path); goto out; }