Date: Wed, 21 Apr 2021 15:26:16 GMT From: Mateusz Guzik <mjg@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 9c651561a2a3 - main - zfs: damage control racing .. lookups in face of mkdir/rmdir Message-ID: <202104211526.13LFQGh8018776@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by mjg: URL: https://cgit.FreeBSD.org/src/commit/?id=9c651561a2a31fcb08390d37947afc27ec03d87b commit 9c651561a2a31fcb08390d37947afc27ec03d87b Author: Mateusz Guzik <mjg@FreeBSD.org> AuthorDate: 2021-04-15 07:54:18 +0000 Commit: Mateusz Guzik <mjg@FreeBSD.org> CommitDate: 2021-04-21 15:25:32 +0000 zfs: damage control racing .. lookups in face of mkdir/rmdir Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D29769 --- .../openzfs/module/os/freebsd/zfs/zfs_vnops_os.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c index 8172916c4329..a1e9c359b893 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_vnops_os.c @@ -781,6 +781,7 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, znode_t *zdp = VTOZ(dvp); znode_t *zp; zfsvfs_t *zfsvfs = zdp->z_zfsvfs; + seqc_t dvp_seqc; int error = 0; /* @@ -806,6 +807,8 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(zdp); + dvp_seqc = vn_seqc_read_any(dvp); + *vpp = NULL; if (flags & LOOKUP_XATTR) { @@ -975,6 +978,24 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t **vpp, } } + 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; + } + } + /* Insert name into cache (as non-existent) if appropriate. */ if (zfsvfs->z_use_namecache && !zfsvfs->z_replay && error == ENOENT && (cnp->cn_flags & MAKEENTRY) != 0)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202104211526.13LFQGh8018776>