@@ -781,6 +781,9 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
781
781
znode_t * zdp = VTOZ (dvp );
782
782
znode_t * zp ;
783
783
zfsvfs_t * zfsvfs = zdp -> z_zfsvfs ;
784
+ #if __FreeBSD_version > 1300124
785
+ seqc_t dvp_seqc ;
786
+ #endif
784
787
int error = 0 ;
785
788
786
789
/*
@@ -806,6 +809,10 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
806
809
ZFS_ENTER (zfsvfs );
807
810
ZFS_VERIFY_ZP (zdp );
808
811
812
+ #if __FreeBSD_version > 1300124
813
+ dvp_seqc = vn_seqc_read_any (dvp );
814
+ #endif
815
+
809
816
* vpp = NULL ;
810
817
811
818
if (flags & LOOKUP_XATTR ) {
@@ -975,6 +982,26 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
975
982
}
976
983
}
977
984
985
+ #if __FreeBSD_version > 1300124
986
+ if ((cnp -> cn_flags & ISDOTDOT ) != 0 ) {
987
+ /*
988
+ * FIXME: zfs_lookup_lock relocks vnodes and does nothing to
989
+ * handle races. In particular different callers may end up
990
+ * with different vnodes and will try to add conflicting
991
+ * entries to the namecache.
992
+ *
993
+ * While finding different result may be acceptable in face
994
+ * of concurrent modification, adding conflicting entries
995
+ * trips over an assert in the namecache.
996
+ *
997
+ * Ultimately let an entry through once everything settles.
998
+ */
999
+ if (!vn_seqc_consistent (dvp , dvp_seqc )) {
1000
+ cnp -> cn_flags &= ~MAKEENTRY ;
1001
+ }
1002
+ }
1003
+ #endif
1004
+
978
1005
/* Insert name into cache (as non-existent) if appropriate. */
979
1006
if (zfsvfs -> z_use_namecache && !zfsvfs -> z_replay &&
980
1007
error == ENOENT && (cnp -> cn_flags & MAKEENTRY ) != 0 )
0 commit comments