From nobody Thu Mar 24 11:22:32 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id E1DA11A4675B; Thu, 24 Mar 2022 11:22:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KPN9h5ywTz4qTF; Thu, 24 Mar 2022 11:22:32 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1648120952; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=acHpjI+iiz8c7Kpmg7ifjApLeKodDJ32PCtKwDOHzcs=; b=dM7kyjH+UMctSDZwwF+2yx9RXMZFORLR5J6Oej/wj5o7OW64oMejXW6ULCaRJcs5NKiI53 kOfAkgtKlbQF695uXkKwDjbex7nVrJY/7kfO7cJ557tpnBVHhWv/p0NnDewmvldD/xk8KN /TkNQ0Z749afrvgR+WomFib+0Be5YfGZvF9jPezxWjQvnSHiTPM2Dir2DbkUaqea7lGJjd l6L/fpSTtGXrVV4pGJrzy4JkzHgar5JVnlXfNDwrg6FK/eZ1i9XlgQaYzgLUZHUx1H/0AU CZcs3tXO/N5bFlIx3nFLqRPMpWffKNbkk2BQgQa1VBzVBeatw4f6d4DXRKoGyA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id ADF0716DD3; Thu, 24 Mar 2022 11:22:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 22OBMWbo084395; Thu, 24 Mar 2022 11:22:32 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22OBMWhZ084394; Thu, 24 Mar 2022 11:22:32 GMT (envelope-from git) Date: Thu, 24 Mar 2022 11:22:32 GMT Message-Id: <202203241122.22OBMWhZ084394@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mateusz Guzik Subject: git: 56244d35741a - main - vfs: hoist degenerate path lookups out of the loop List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mjg X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 56244d35741a62e725786fc96e7d3d962677c0ad Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1648120952; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=acHpjI+iiz8c7Kpmg7ifjApLeKodDJ32PCtKwDOHzcs=; b=sjlsJJ/W3vx5Tu7PbpgQ9N5JZ08drWUr5uw2TcwBPVeabK9lr+EeIq1scAU4uVxQNSJq/x pjkL85bXE/iXrEa0CfAX2pgsVyNYt2HrfMSJ0A3bAPQk4TSUgWBVuyo48VKtUFYa3jqFvM xmNzFo7CVAJgkVPUFwU3/yIkc1FCSzYI76ML3FywqL9BdcvqWEo2IZ6JDKmN5cmFTfRNLi BKyWTrwFZjyskqzpxUJtQqFkvyFw3n6ou8lt9wBr62d3ZTA4VRu7RUxTD9uwdp/37lUZ9V eVtJGo4NgHk5eKqnSul0+cQg5372yYYKH9LWckUkxH9t5fZ2plQLZqc8BXdL5w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1648120952; a=rsa-sha256; cv=none; b=HeOq9C5rlXJJJvRgsdk3XtMdRIqGSegXG4pcPp28b+MI6PjIiTa6YagV44zNzCNxivRP97 cxrUa/UHVpQbipXwzb3WKguGNinFOv6BoS9p7SUhEt5rLfAJ6+2rKCIUgJDgptcXNweIrX CxTJUewUL5QgQR6RqDzwVKWJzGG3h2cvNMOIqVs5oUqcaqQvw0sIOlGnaAnEmyqdE2rYgA L2+fMtc5+rtS2gmfhVukRP82w/FWeZz5Ak+NCNh6KAq5osCVF0FEBvRUzeCnZWANe8/Ivk ztFxp0RG6bn38oenM2+oHSPOYwB+0KBH3RaTmYVEk7uX3TOdt6DMVtBA94335Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by mjg: URL: https://cgit.FreeBSD.org/src/commit/?id=56244d35741a62e725786fc96e7d3d962677c0ad commit 56244d35741a62e725786fc96e7d3d962677c0ad Author: Mateusz Guzik AuthorDate: 2022-03-11 15:51:39 +0000 Commit: Mateusz Guzik CommitDate: 2022-03-24 11:22:12 +0000 vfs: hoist degenerate path lookups out of the loop --- sys/kern/vfs_lookup.c | 110 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 33 deletions(-) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 5a0871c91fac..f4fabe55b06e 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -802,6 +802,57 @@ needs_exclusive_leaf(struct mount *mp, int flags) _Static_assert(MAXNAMLEN == NAME_MAX, "MAXNAMLEN and NAME_MAX have different values"); +static int __noinline +vfs_lookup_degenerate(struct nameidata *ndp, struct vnode *dp, int wantparent) +{ + struct componentname *cnp; + struct mount *mp; + int error; + + cnp = &ndp->ni_cnd; + + cnp->cn_flags |= ISLASTCN; + + mp = atomic_load_ptr(&dp->v_mount); + if (needs_exclusive_leaf(mp, cnp->cn_flags)) { + cnp->cn_lkflags &= ~LK_SHARED; + cnp->cn_lkflags |= LK_EXCLUSIVE; + } + + vn_lock(dp, + compute_cn_lkflags(mp, cnp->cn_lkflags | LK_RETRY, + cnp->cn_flags)); + + if (dp->v_type != VDIR) { + error = ENOTDIR; + goto bad; + } + if (cnp->cn_nameiop != LOOKUP) { + error = EISDIR; + goto bad; + } + if (wantparent) { + ndp->ni_dvp = dp; + VREF(dp); + } + ndp->ni_vp = dp; + + if (cnp->cn_flags & AUDITVNODE1) + AUDIT_ARG_VNODE1(dp); + else if (cnp->cn_flags & AUDITVNODE2) + AUDIT_ARG_VNODE2(dp); + + if (!(cnp->cn_flags & (LOCKPARENT | LOCKLEAF))) + VOP_UNLOCK(dp); + /* XXX This should probably move to the top of function. */ + if (cnp->cn_flags & SAVESTART) + panic("lookup: SAVESTART"); + return (0); +bad: + VOP_UNLOCK(dp); + return (error); +} + /* * Search a pathname. * This is a very central and rather complicated routine. @@ -886,13 +937,31 @@ vfs_lookup(struct nameidata *ndp) rdonly = cnp->cn_flags & RDONLY; cnp->cn_flags &= ~ISSYMLINK; ndp->ni_dvp = NULL; + + cnp->cn_lkflags = LK_SHARED; + dp = ndp->ni_startdir; + ndp->ni_startdir = NULLVP; + + /* + * Leading slashes, if any, are supposed to be skipped by the caller. + */ + MPASS(cnp->cn_nameptr[0] != '/'); + + /* + * Check for degenerate name (e.g. / or "") which is a way of talking + * about a directory, e.g. like "/." or ".". + */ + if (__predict_false(cnp->cn_nameptr[0] == '\0')) { + error = vfs_lookup_degenerate(ndp, dp, wantparent); + if (error == 0) + goto success_right_lock; + goto bad_unlocked; + } + /* * We use shared locks until we hit the parent of the last cn then * we adjust based on the requesting flags. */ - cnp->cn_lkflags = LK_SHARED; - dp = ndp->ni_startdir; - ndp->ni_startdir = NULLVP; vn_lock(dp, compute_cn_lkflags(dp->v_mount, cnp->cn_lkflags | LK_RETRY, cnp->cn_flags)); @@ -980,37 +1049,10 @@ dirloop: nameicap_tracker_add(ndp, dp); /* - * Check for degenerate name (e.g. / or "") - * which is a way of talking about a directory, - * e.g. like "/." or ".". + * Make sure degenerate names don't get here, their handling was + * previously found in this spot. */ - if (cnp->cn_nameptr[0] == '\0') { - if (dp->v_type != VDIR) { - error = ENOTDIR; - goto bad; - } - if (cnp->cn_nameiop != LOOKUP) { - error = EISDIR; - goto bad; - } - if (wantparent) { - ndp->ni_dvp = dp; - VREF(dp); - } - ndp->ni_vp = dp; - - if (cnp->cn_flags & AUDITVNODE1) - AUDIT_ARG_VNODE1(dp); - else if (cnp->cn_flags & AUDITVNODE2) - AUDIT_ARG_VNODE2(dp); - - if (!(cnp->cn_flags & (LOCKPARENT | LOCKLEAF))) - VOP_UNLOCK(dp); - /* XXX This should probably move to the top of function. */ - if (cnp->cn_flags & SAVESTART) - panic("lookup: SAVESTART"); - goto success; - } + MPASS(cnp->cn_nameptr[0] != '\0'); /* * Handle "..": five special cases. @@ -1341,6 +1383,7 @@ success: goto bad2; } } +success_right_lock: if (ndp->ni_vp != NULL) { if ((cnp->cn_flags & ISDOTDOT) == 0) nameicap_tracker_add(ndp, ndp->ni_vp); @@ -1359,6 +1402,7 @@ bad2: bad: if (!dpunlocked) vput(dp); +bad_unlocked: ndp->ni_vp = NULL; return (error); bad_eexist: