Skip to content

Commit 05e25a8

Browse files
committed
FreeBSD: damage control racing .. lookups in face of mkdir/rmdir
Signed-off-by: Mateusz Guzik <[email protected]>
1 parent 60ffc1c commit 05e25a8

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

module/os/freebsd/zfs/zfs_vnops_os.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,9 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
781781
znode_t *zdp = VTOZ(dvp);
782782
znode_t *zp;
783783
zfsvfs_t *zfsvfs = zdp->z_zfsvfs;
784+
#if __FreeBSD_version > 1300124
785+
seqc_t dvp_seqc;
786+
#endif
784787
int error = 0;
785788

786789
/*
@@ -806,6 +809,10 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
806809
ZFS_ENTER(zfsvfs);
807810
ZFS_VERIFY_ZP(zdp);
808811

812+
#if __FreeBSD_version > 1300124
813+
dvp_seqc = vn_seqc_read_any(dvp);
814+
#endif
815+
809816
*vpp = NULL;
810817

811818
if (flags & LOOKUP_XATTR) {
@@ -975,6 +982,26 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
975982
}
976983
}
977984

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+
9781005
/* Insert name into cache (as non-existent) if appropriate. */
9791006
if (zfsvfs->z_use_namecache && !zfsvfs->z_replay &&
9801007
error == ENOENT && (cnp->cn_flags & MAKEENTRY) != 0)

0 commit comments

Comments
 (0)