Skip to content

Commit 79c5a67

Browse files
mjguzikRyan Moeller
authored andcommitted
FreeBSD: damage control racing .. lookups in face of mkdir/rmdir
External-issue: https://reviews.freebsd.org/D29769 Reviewed-by: Alexander Motin <[email protected]> Reviewed-by: Ryan Moeller <[email protected]> Signed-off-by: Mateusz Guzik <[email protected]> Closes openzfs#11926
1 parent 0f7a9ee commit 79c5a67

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
@@ -1013,6 +1013,9 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
10131013
znode_t *zdp = VTOZ(dvp);
10141014
znode_t *zp;
10151015
zfsvfs_t *zfsvfs = zdp->z_zfsvfs;
1016+
#if __FreeBSD_version > 1300124
1017+
seqc_t dvp_seqc;
1018+
#endif
10161019
int error = 0;
10171020

10181021
/*
@@ -1038,6 +1041,10 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
10381041
ZFS_ENTER(zfsvfs);
10391042
ZFS_VERIFY_ZP(zdp);
10401043

1044+
#if __FreeBSD_version > 1300124
1045+
dvp_seqc = vn_seqc_read_notmodify(dvp);
1046+
#endif
1047+
10411048
*vpp = NULL;
10421049

10431050
if (flags & LOOKUP_XATTR) {
@@ -1207,6 +1214,26 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
12071214
}
12081215
}
12091216

1217+
#if __FreeBSD_version > 1300124
1218+
if ((cnp->cn_flags & ISDOTDOT) != 0) {
1219+
/*
1220+
* FIXME: zfs_lookup_lock relocks vnodes and does nothing to
1221+
* handle races. In particular different callers may end up
1222+
* with different vnodes and will try to add conflicting
1223+
* entries to the namecache.
1224+
*
1225+
* While finding different result may be acceptable in face
1226+
* of concurrent modification, adding conflicting entries
1227+
* trips over an assert in the namecache.
1228+
*
1229+
* Ultimately let an entry through once everything settles.
1230+
*/
1231+
if (!vn_seqc_consistent(dvp, dvp_seqc)) {
1232+
cnp->cn_flags &= ~MAKEENTRY;
1233+
}
1234+
}
1235+
#endif
1236+
12101237
/* Insert name into cache (as non-existent) if appropriate. */
12111238
if (zfsvfs->z_use_namecache && !zfsvfs->z_replay &&
12121239
error == ENOENT && (cnp->cn_flags & MAKEENTRY) != 0)

0 commit comments

Comments
 (0)