Skip site navigation (1)Skip section navigation (2)
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>