From owner-freebsd-fs@freebsd.org Wed Jul 8 22:07:22 2015 Return-Path: Delivered-To: freebsd-fs@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 6F31C99652D for ; Wed, 8 Jul 2015 22:07:22 +0000 (UTC) (envelope-from mjguzik@gmail.com) Received: from mail-wg0-x22b.google.com (mail-wg0-x22b.google.com [IPv6:2a00:1450:400c:c00::22b]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 08ADD30D2; Wed, 8 Jul 2015 22:07:22 +0000 (UTC) (envelope-from mjguzik@gmail.com) Received: by wgjx7 with SMTP id x7so207479549wgj.2; Wed, 08 Jul 2015 15:07:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jvj7cH8+cgwNkf73qZezOjznS2iqXNeBVNnPWVldj3k=; b=ASCzcuo5Kon1sQKTnLWubUvJ3WzTPI7WB+i9tuJZ0dKTnu4hvK2rnENiv5F+wz9T7L KOIIvsI7NmcjKSeDdw9hnOEuhiOIvz3HKrxG2MwGV8jkhwPk56kFeZjiXqGVcJcnqFln 8+vN8UVeu4ZBRw22bhEMmfYF4h0ibXechqc4gwXN5e2MH6O/dl1YXJWssw09ZcJcgJn1 YSMZNztdTgczAp+MRDKMYNWp/+Qbmq0YFvpmWhhdl6KooeB1/xlJm/hYM8GdfQCDllaK 3OSsEtc85c5hp08xqlhpqDdCfAPSFZRvW16AtnznxjpQFL5bIjGJmTZP/N284t+dylS0 U5vA== X-Received: by 10.194.9.161 with SMTP id a1mr23408484wjb.39.1436393240551; Wed, 08 Jul 2015 15:07:20 -0700 (PDT) Received: from localhost.localdomain (ip-89-102-11-63.net.upcbroadband.cz. [89.102.11.63]) by smtp.gmail.com with ESMTPSA id fo17sm5483921wjc.46.2015.07.08.15.07.19 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 08 Jul 2015 15:07:19 -0700 (PDT) From: Mateusz Guzik To: Konstantin Belousov Cc: rwatson@FreeBSD.org, freebsd-fs@freebsd.org, Mateusz Guzik Subject: [PATCH 3/4] vfs: simplify error handling in namei Date: Thu, 9 Jul 2015 00:07:10 +0200 Message-Id: <1436393231-5831-4-git-send-email-mjguzik@gmail.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1436393231-5831-1-git-send-email-mjguzik@gmail.com> References: <20150707085857.GZ2080@kib.kiev.ua> <1436393231-5831-1-git-send-email-mjguzik@gmail.com> X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jul 2015 22:07:22 -0000 From: Mateusz Guzik The logic is reorganised so that there is one exit point prior to the lookup loop. This is an intermediate step to making audit logging functions use found vnode instead of translating ni_dirfd on their own. ni_startdir validation is removed. The only in-tree consumer is nfs which already makes sure it is a directory. --- sys/kern/vfs_lookup.c | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index e434464..d48fcff 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -158,7 +158,7 @@ namei(struct nameidata *ndp) struct vnode *dp; /* the directory we are searching */ struct iovec aiov; /* uio for reading symbolic links */ struct uio auio; - int error, linklen; + int error, linklen, startdir_used; struct componentname *cnp = &ndp->ni_cnd; struct thread *td = cnp->cn_thread; struct proc *p = td->td_proc; @@ -169,6 +169,9 @@ namei(struct nameidata *ndp) ("namei: nameiop contaminated with flags")); KASSERT((cnp->cn_flags & OPMASK) == 0, ("namei: flags contaminated with nameiops")); + if (ndp->ni_startdir != NULL) + MPASS(ndp->ni_startdir->v_type == VDIR || + ndp->ni_startdir->v_type == VBAD); if (!lookup_shared) cnp->cn_flags &= ~LOCKSHARED; fdp = p->p_fd; @@ -242,23 +245,19 @@ namei(struct nameidata *ndp) if (cnp->cn_flags & AUDITVNODE2) AUDIT_ARG_UPATH2(td, ndp->ni_dirfd, cnp->cn_pnbuf); + startdir_used = 0; dp = NULL; cnp->cn_nameptr = cnp->cn_pnbuf; if (cnp->cn_pnbuf[0] == '/') { error = namei_handle_root(ndp, &dp); - FILEDESC_SUNLOCK(fdp); - if (error != 0) { - vrele(ndp->ni_rootdir); - if (ndp->ni_startdir != NULL) - vrele(ndp->ni_startdir); - namei_cleanup_cnp(cnp); - return (error); - } } else { if (ndp->ni_startdir != NULL) { dp = ndp->ni_startdir; - error = 0; - } else if (ndp->ni_dirfd != AT_FDCWD) { + startdir_used = 1; + } else if (ndp->ni_dirfd == AT_FDCWD) { + dp = fdp->fd_cdir; + VREF(dp); + } else { cap_rights_t rights; rights = ndp->ni_rightsneeded; @@ -285,25 +284,18 @@ namei(struct nameidata *ndp) } #endif } - if (error != 0 || dp != NULL) { - FILEDESC_SUNLOCK(fdp); - if (error == 0 && dp->v_type != VDIR) { - vrele(dp); - error = ENOTDIR; - } - } - if (error) { - vrele(ndp->ni_rootdir); - namei_cleanup_cnp(cnp); - return (error); - } + if (error == 0 && dp->v_type != VDIR) + error = ENOTDIR; } - if (dp == NULL) { - dp = fdp->fd_cdir; - VREF(dp); - FILEDESC_SUNLOCK(fdp); - if (ndp->ni_startdir != NULL) - vrele(ndp->ni_startdir); + FILEDESC_SUNLOCK(fdp); + if (ndp->ni_startdir != NULL && !startdir_used) + vrele(ndp->ni_startdir); + if (error != 0) { + if (dp != NULL) + vrele(dp); + vrele(ndp->ni_rootdir); + namei_cleanup_cnp(cnp); + return (error); } SDT_PROBE(vfs, namei, lookup, entry, dp, cnp->cn_pnbuf, cnp->cn_flags, 0, 0); -- 2.4.5