FreeBSD: damage control racing .. lookups in face of mkdir/rmdir
External-issue: https://reviews.freebsd.org/D29769 Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Signed-off-by: Mateusz Guzik <mjguzik@gmail.com> Closes #11926
This commit is contained in:
parent
e5c01296ff
commit
1b7d883eaa
|
@ -781,6 +781,9 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
|
||||||
znode_t *zdp = VTOZ(dvp);
|
znode_t *zdp = VTOZ(dvp);
|
||||||
znode_t *zp;
|
znode_t *zp;
|
||||||
zfsvfs_t *zfsvfs = zdp->z_zfsvfs;
|
zfsvfs_t *zfsvfs = zdp->z_zfsvfs;
|
||||||
|
#if __FreeBSD_version > 1300124
|
||||||
|
seqc_t dvp_seqc;
|
||||||
|
#endif
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -806,6 +809,10 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
|
||||||
ZFS_ENTER(zfsvfs);
|
ZFS_ENTER(zfsvfs);
|
||||||
ZFS_VERIFY_ZP(zdp);
|
ZFS_VERIFY_ZP(zdp);
|
||||||
|
|
||||||
|
#if __FreeBSD_version > 1300124
|
||||||
|
dvp_seqc = vn_seqc_read_notmodify(dvp);
|
||||||
|
#endif
|
||||||
|
|
||||||
*vpp = NULL;
|
*vpp = NULL;
|
||||||
|
|
||||||
if (flags & LOOKUP_XATTR) {
|
if (flags & LOOKUP_XATTR) {
|
||||||
|
@ -975,6 +982,26 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if __FreeBSD_version > 1300124
|
||||||
|
if ((cnp->cn_flags & ISDOTDOT) != 0) {
|
||||||
|
/*
|
||||||
|
* FIXME: zfs_lookup_lock relocks vnodes and does nothing to
|
||||||
|
* handle races. In particular different callers may end up
|
||||||
|
* with different vnodes and will try to add conflicting
|
||||||
|
* entries to the namecache.
|
||||||
|
*
|
||||||
|
* While finding different result may be acceptable in face
|
||||||
|
* of concurrent modification, adding conflicting entries
|
||||||
|
* trips over an assert in the namecache.
|
||||||
|
*
|
||||||
|
* Ultimately let an entry through once everything settles.
|
||||||
|
*/
|
||||||
|
if (!vn_seqc_consistent(dvp, dvp_seqc)) {
|
||||||
|
cnp->cn_flags &= ~MAKEENTRY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Insert name into cache (as non-existent) if appropriate. */
|
/* Insert name into cache (as non-existent) if appropriate. */
|
||||||
if (zfsvfs->z_use_namecache && !zfsvfs->z_replay &&
|
if (zfsvfs->z_use_namecache && !zfsvfs->z_replay &&
|
||||||
error == ENOENT && (cnp->cn_flags & MAKEENTRY) != 0)
|
error == ENOENT && (cnp->cn_flags & MAKEENTRY) != 0)
|
||||||
|
|
Loading…
Reference in New Issue