Re: git: 5b5b7e2ca2fa - main - vfs: always retain path buffer after lookup

From: Mateusz Guzik <mjguzik_at_gmail.com>
Date: Sun, 18 Sep 2022 18:27:10 UTC
On 9/17/22, Mitchell Horne <mhorne@freebsd.org> wrote:
>
>
> On 9/17/22 06:11, Mateusz Guzik wrote:
>> The branch main has been updated by mjg:
>>
>> URL:
>> https://cgit.FreeBSD.org/src/commit/?id=5b5b7e2ca2fa9a2418dd51749f4ef6f881ae7179
>>
>> commit 5b5b7e2ca2fa9a2418dd51749f4ef6f881ae7179
>> Author:     Mateusz Guzik <mjg@FreeBSD.org>
>> AuthorDate: 2022-09-17 09:10:38 +0000
>> Commit:     Mateusz Guzik <mjg@FreeBSD.org>
>> CommitDate: 2022-09-17 09:10:38 +0000
>>
>>      vfs: always retain path buffer after lookup
>>
>>      This removes some of the complexity needed to maintain HASBUF and
>>      allows for removing injecting SAVENAME by filesystems.
>>
>
> Hi,
>
> Will you update namei(9) to reflect that the SAVENAME flag has been
> removed? That page seems to be somewhat stale already, but it should be
> done nonetheless.
>

I'll consider it after I'm done cleaning up the interface.

> Cheers,
> Mitchell
>
>>      Reviewed by:    kib (previous version)
>>      Differential Revision:  https://reviews.freebsd.org/D36542
>> ---
>>   .../openzfs/module/os/freebsd/zfs/zfs_vnops_os.c   |  23 +++-
>>   sys/fs/devfs/devfs_vnops.c                         |   1 -
>>   sys/fs/ext2fs/ext2_lookup.c                        |   8 --
>>   sys/fs/ext2fs/ext2_vnops.c                         |  17 ---
>>   sys/fs/fuse/fuse_vnops.c                           |  14 ---
>>   sys/fs/msdosfs/msdosfs_lookup.c                    |   4 -
>>   sys/fs/msdosfs/msdosfs_vnops.c                     |  13 ---
>>   sys/fs/nfsclient/nfs_clvnops.c                     |  14 ---
>>   sys/fs/nfsserver/nfs_nfsdport.c                    |  21 ++--
>>   sys/fs/nfsserver/nfs_nfsdserv.c                    |   8 +-
>>   sys/fs/smbfs/smbfs_vnops.c                         |   5 -
>>   sys/fs/tmpfs/tmpfs_subr.c                          |   1 -
>>   sys/fs/tmpfs/tmpfs_vnops.c                         |  10 --
>>   sys/fs/unionfs/union_subr.c                        |  25 +---
>>   sys/fs/unionfs/union_vnops.c                       |   9 --
>>   sys/kern/kern_exec.c                               |   2 +-
>>   sys/kern/uipc_mqueue.c                             |   5 -
>>   sys/kern/uipc_usrreq.c                             |   4 +-
>>   sys/kern/vfs_cache.c                               |  34 ++----
>>   sys/kern/vfs_lookup.c                              | 127
>> ++-------------------
>>   sys/kern/vfs_subr.c                                |   2 +-
>>   sys/kern/vfs_syscalls.c                            |  50 ++++----
>>   sys/sys/namei.h                                    |  32 ++----
>>   sys/sys/param.h                                    |   2 +-
>>   sys/ufs/ufs/ufs_lookup.c                           |   6 -
>>   sys/ufs/ufs/ufs_vnops.c                            |  20 ----
>>   26 files changed, 96 insertions(+), 361 deletions(-)
>>
>> 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 b46cc550c781..a102ce2e99a9 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
>> @@ -965,13 +965,17 @@ zfs_lookup(vnode_t *dvp, const char *nm, vnode_t
>> **vpp,
>>   		case RENAME:
>>   			if (error == ENOENT) {
>>   				error = EJUSTRETURN;
>> +#if __FreeBSD_version < 1400068
>>   				cnp->cn_flags |= SAVENAME;
>> +#endif
>>   				break;
>>   			}
>>   			zfs_fallthrough;
>>   		case DELETE:
>> +#if __FreeBSD_version < 1400068
>>   			if (error == 0)
>>   				cnp->cn_flags |= SAVENAME;
>> +#endif
>>   			break;
>>   		}
>>   	}
>> @@ -1318,7 +1322,10 @@ zfs_lookup_internal(znode_t *dzp, const char *name,
>> vnode_t **vpp,
>>   	cnp->cn_nameptr = __DECONST(char *, name);
>>   	cnp->cn_namelen = strlen(name);
>>   	cnp->cn_nameiop = nameiop;
>> -	cnp->cn_flags = ISLASTCN | SAVENAME;
>> +	cnp->cn_flags = ISLASTCN;
>> +#if __FreeBSD_version < 1400068
>> +	cnp->cn_flags |= SAVENAME;
>> +#endif
>>   	cnp->cn_lkflags = LK_EXCLUSIVE | LK_RETRY;
>>   	cnp->cn_cred = kcred;
>>   #if __FreeBSD_version < 1400037
>> @@ -4620,7 +4627,9 @@ zfs_freebsd_create(struct vop_create_args *ap)
>>   	znode_t *zp = NULL;
>>   	int rc, mode;
>>
>> +#if __FreeBSD_version < 1400068
>>   	ASSERT(cnp->cn_flags & SAVENAME);
>> +#endif
>>
>>   	vattr_init_mask(vap);
>>   	mode = vap->va_mode & ALLPERMS;
>> @@ -4650,7 +4659,9 @@ static int
>>   zfs_freebsd_remove(struct vop_remove_args *ap)
>>   {
>>
>> +#if __FreeBSD_version < 1400068
>>   	ASSERT(ap->a_cnp->cn_flags & SAVENAME);
>> +#endif
>>
>>   	return (zfs_remove_(ap->a_dvp, ap->a_vp, ap->a_cnp->cn_nameptr,
>>   	    ap->a_cnp->cn_cred));
>> @@ -4672,7 +4683,9 @@ zfs_freebsd_mkdir(struct vop_mkdir_args *ap)
>>   	znode_t *zp = NULL;
>>   	int rc;
>>
>> +#if __FreeBSD_version < 1400068
>>   	ASSERT(ap->a_cnp->cn_flags & SAVENAME);
>> +#endif
>>
>>   	vattr_init_mask(vap);
>>   	*ap->a_vpp = NULL;
>> @@ -4698,7 +4711,9 @@ zfs_freebsd_rmdir(struct vop_rmdir_args *ap)
>>   {
>>   	struct componentname *cnp = ap->a_cnp;
>>
>> +#if __FreeBSD_version < 1400068
>>   	ASSERT(cnp->cn_flags & SAVENAME);
>> +#endif
>>
>>   	return (zfs_rmdir_(ap->a_dvp, ap->a_vp, cnp->cn_nameptr,
>> cnp->cn_cred));
>>   }
>> @@ -4952,8 +4967,10 @@ zfs_freebsd_rename(struct vop_rename_args *ap)
>>   	vnode_t *tvp = ap->a_tvp;
>>   	int error;
>>
>> +#if __FreeBSD_version < 1400068
>>   	ASSERT(ap->a_fcnp->cn_flags & (SAVENAME|SAVESTART));
>>   	ASSERT(ap->a_tcnp->cn_flags & (SAVENAME|SAVESTART));
>> +#endif
>>
>>   	error = zfs_do_rename(fdvp, &fvp, ap->a_fcnp, tdvp, &tvp,
>>   	    ap->a_tcnp, ap->a_fcnp->cn_cred);
>> @@ -4989,7 +5006,9 @@ zfs_freebsd_symlink(struct vop_symlink_args *ap)
>>   #endif
>>   	int rc;
>>
>> +#if __FreeBSD_version < 1400068
>>   	ASSERT(cnp->cn_flags & SAVENAME);
>> +#endif
>>
>>   	vap->va_type = VLNK;	/* FreeBSD: Syscall only sets va_mode. */
>>   	vattr_init_mask(vap);
>> @@ -5083,7 +5102,9 @@ zfs_freebsd_link(struct vop_link_args *ap)
>>   	if (tdvp->v_mount != vp->v_mount)
>>   		return (EXDEV);
>>
>> +#if __FreeBSD_version < 1400068
>>   	ASSERT(cnp->cn_flags & SAVENAME);
>> +#endif
>>
>>   	return (zfs_link(VTOZ(tdvp), VTOZ(vp),
>>   	    cnp->cn_nameptr, cnp->cn_cred, 0));
>> diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
>> index 13619d318cfc..511430ccdd97 100644
>> --- a/sys/fs/devfs/devfs_vnops.c
>> +++ b/sys/fs/devfs/devfs_vnops.c
>> @@ -1140,7 +1140,6 @@ devfs_lookupx(struct vop_lookup_args *ap, int
>> *dm_unlock)
>>   	if (de == NULL || de->de_flags & DE_WHITEOUT) {
>>   		if ((nameiop == CREATE || nameiop == RENAME) &&
>>   		    (flags & (LOCKPARENT | WANTPARENT)) && (flags & ISLASTCN)) {
>> -			cnp->cn_flags |= SAVENAME;
>>   			return (EJUSTRETURN);
>>   		}
>>   		return (ENOENT);
>> diff --git a/sys/fs/ext2fs/ext2_lookup.c b/sys/fs/ext2fs/ext2_lookup.c
>> index a8e28e24f9e2..16f2aa88b28c 100644
>> --- a/sys/fs/ext2fs/ext2_lookup.c
>> +++ b/sys/fs/ext2fs/ext2_lookup.c
>> @@ -514,13 +514,10 @@ notfound:
>>   		 * We return ni_vp == NULL to indicate that the entry
>>   		 * does not currently exist; we leave a pointer to
>>   		 * the (locked) directory inode in ndp->ni_dvp.
>> -		 * The pathname buffer is saved so that the name
>> -		 * can be obtained later.
>>   		 *
>>   		 * NB - if the directory is unlocked, then this
>>   		 * information cannot be used.
>>   		 */
>> -		cnp->cn_flags |= SAVENAME;
>>   		return (EJUSTRETURN);
>>   	}
>>   	/*
>> @@ -631,7 +628,6 @@ found:
>>   		    &tdp)) != 0)
>>   			return (error);
>>   		*vpp = tdp;
>> -		cnp->cn_flags |= SAVENAME;
>>   		return (0);
>>   	}
>>   	if (dd_ino != NULL)
>> @@ -925,10 +921,6 @@ ext2_direnter(struct inode *ip, struct vnode *dvp,
>> struct componentname *cnp)
>>   	int DIRBLKSIZ = ip->i_e2fs->e2fs_bsize;
>>   	int error;
>>
>> -#ifdef INVARIANTS
>> -	if ((cnp->cn_flags & SAVENAME) == 0)
>> -		panic("ext2_direnter: missing name");
>> -#endif
>>   	dp = VTOI(dvp);
>>   	newdir.e2d_ino = htole32(ip->i_number);
>>   	if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs,
>> diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c
>> index 9843fc16e6b2..b629ddefcd1a 100644
>> --- a/sys/fs/ext2fs/ext2_vnops.c
>> +++ b/sys/fs/ext2fs/ext2_vnops.c
>> @@ -709,10 +709,6 @@ ext2_link(struct vop_link_args *ap)
>>   	struct inode *ip;
>>   	int error;
>>
>> -#ifdef INVARIANTS
>> -	if ((cnp->cn_flags & HASBUF) == 0)
>> -		panic("ext2_link: no name");
>> -#endif
>>   	ip = VTOI(vp);
>>   	if ((nlink_t)ip->i_nlink >= EXT4_LINK_MAX) {
>>   		error = EMLINK;
>> @@ -801,11 +797,6 @@ ext2_rename(struct vop_rename_args *ap)
>>   	int error = 0;
>>   	u_char namlen;
>>
>> -#ifdef INVARIANTS
>> -	if ((tcnp->cn_flags & HASBUF) == 0 ||
>> -	    (fcnp->cn_flags & HASBUF) == 0)
>> -		panic("ext2_rename: no name");
>> -#endif
>>   	/*
>>   	 * Check for cross-device rename.
>>   	 */
>> @@ -1315,10 +1306,6 @@ ext2_mkdir(struct vop_mkdir_args *ap)
>>   	char *buf = NULL;
>>   	int error, dmode;
>>
>> -#ifdef INVARIANTS
>> -	if ((cnp->cn_flags & HASBUF) == 0)
>> -		panic("ext2_mkdir: no name");
>> -#endif
>>   	dp = VTOI(dvp);
>>   	if ((nlink_t)dp->i_nlink >= EXT4_LINK_MAX &&
>>   	    !EXT2_HAS_RO_COMPAT_FEATURE(dp->i_e2fs, EXT2F_ROCOMPAT_DIR_NLINK))
>> {
>> @@ -1946,10 +1933,6 @@ ext2_makeinode(int mode, struct vnode *dvp, struct
>> vnode **vpp,
>>   	int error;
>>
>>   	pdir = VTOI(dvp);
>> -#ifdef INVARIANTS
>> -	if ((cnp->cn_flags & HASBUF) == 0)
>> -		panic("ext2_makeinode: no name");
>> -#endif
>>   	*vpp = NULL;
>>   	if ((mode & IFMT) == 0)
>>   		mode |= IFREG;
>> diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c
>> index 845ea04eca93..e89b831a4859 100644
>> --- a/sys/fs/fuse/fuse_vnops.c
>> +++ b/sys/fs/fuse/fuse_vnops.c
>> @@ -1391,7 +1391,6 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
>>
>>   	int nameiop = cnp->cn_nameiop;
>>   	int flags = cnp->cn_flags;
>> -	int wantparent = flags & (LOCKPARENT | WANTPARENT);
>>   	int islastcn = flags & ISLASTCN;
>>   	struct mount *mp = vnode_mount(dvp);
>>   	struct fuse_data *data = fuse_get_mpdata(mp);
>> @@ -1533,13 +1532,6 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
>>   			else
>>   				err = 0;
>>   			if (!err) {
>> -				/*
>> -				 * Set the SAVENAME flag to hold onto the
>> -				 * pathname for use later in VOP_CREATE or
>> -				 * VOP_RENAME.
>> -				 */
>> -				cnp->cn_flags |= SAVENAME;
>> -
>>   				err = EJUSTRETURN;
>>   			}
>>   		} else {
>> @@ -1619,12 +1611,6 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
>>   					goto out;
>>   				}
>>   			}
>> -
>> -			if (islastcn && (
>> -				(nameiop == DELETE) ||
>> -				(nameiop == RENAME && wantparent))) {
>> -				cnp->cn_flags |= SAVENAME;
>> -			}
>>   		}
>>   	}
>>   out:
>> diff --git a/sys/fs/msdosfs/msdosfs_lookup.c
>> b/sys/fs/msdosfs/msdosfs_lookup.c
>> index 91b778b8173b..c061a9169f25 100644
>> --- a/sys/fs/msdosfs/msdosfs_lookup.c
>> +++ b/sys/fs/msdosfs/msdosfs_lookup.c
>> @@ -421,13 +421,10 @@ notfound:
>>   		 * We return ni_vp == NULL to indicate that the entry
>>   		 * does not currently exist; we leave a pointer to
>>   		 * the (locked) directory inode in ndp->ni_dvp.
>> -		 * The pathname buffer is saved so that the name
>> -		 * can be obtained later.
>>   		 *
>>   		 * NB - if the directory is unlocked, then this
>>   		 * information cannot be used.
>>   		 */
>> -		cnp->cn_flags |= SAVENAME;
>>   		return (EJUSTRETURN);
>>   	}
>>   #if 0
>> @@ -554,7 +551,6 @@ foundroot:
>>   		if ((error = msdosfs_lookup_checker(pmp, vdp, tdp, vpp))
>>   		    != 0)
>>   			return (error);
>> -		cnp->cn_flags |= SAVENAME;
>>   		return (0);
>>   	}
>>
>> diff --git a/sys/fs/msdosfs/msdosfs_vnops.c
>> b/sys/fs/msdosfs/msdosfs_vnops.c
>> index 36da35257d2c..f5a07cd5f492 100644
>> --- a/sys/fs/msdosfs/msdosfs_vnops.c
>> +++ b/sys/fs/msdosfs/msdosfs_vnops.c
>> @@ -161,10 +161,6 @@ msdosfs_create(struct vop_create_args *ap)
>>   	 * use the absence of the owner write bit to make the file
>>   	 * readonly.
>>   	 */
>> -#ifdef DIAGNOSTIC
>> -	if ((cnp->cn_flags & HASBUF) == 0)
>> -		panic("msdosfs_create: no name");
>> -#endif
>>   	memset(&ndirent, 0, sizeof(ndirent));
>>   	error = uniqdosname(pdep, cnp, ndirent.de_Name);
>>   	if (error)
>> @@ -958,11 +954,6 @@ msdosfs_rename(struct vop_rename_args *ap)
>>   	fcnp = ap->a_fcnp;
>>   	pmp = VFSTOMSDOSFS(fdvp->v_mount);
>>
>> -#ifdef DIAGNOSTIC
>> -	if ((tcnp->cn_flags & HASBUF) == 0 ||
>> -	    (fcnp->cn_flags & HASBUF) == 0)
>> -		panic("msdosfs_rename: no name");
>> -#endif
>>   	/*
>>   	 * Check for cross-device rename.
>>   	 */
>> @@ -1414,10 +1405,6 @@ msdosfs_mkdir(struct vop_mkdir_args *ap)
>>   	 * cluster.  This will be written to an empty slot in the parent
>>   	 * directory.
>>   	 */
>> -#ifdef DIAGNOSTIC
>> -	if ((cnp->cn_flags & HASBUF) == 0)
>> -		panic("msdosfs_mkdir: no name");
>> -#endif
>>   	error = uniqdosname(pdep, cnp, ndirent.de_Name);
>>   	if (error)
>>   		goto bad;
>> diff --git a/sys/fs/nfsclient/nfs_clvnops.c
>> b/sys/fs/nfsclient/nfs_clvnops.c
>> index b1a174f171fa..817c1093374c 100644
>> --- a/sys/fs/nfsclient/nfs_clvnops.c
>> +++ b/sys/fs/nfsclient/nfs_clvnops.c
>> @@ -1250,10 +1250,6 @@ nfs_lookup(struct vop_lookup_args *ap)
>>   		 * associated locking bookkeeping, etc.
>>   		 */
>>   		if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
>> -			/* XXX: Is this really correct? */
>> -			if (cnp->cn_nameiop != LOOKUP &&
>> -			    (flags & ISLASTCN))
>> -				cnp->cn_flags |= SAVENAME;
>>   			return (0);
>>   		}
>>
>> @@ -1288,9 +1284,6 @@ nfs_lookup(struct vop_lookup_args *ap)
>>   		    VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 &&
>>   		    timespeccmp(&vattr.va_ctime, &nctime, ==))) {
>>   			NFSINCRGLOBAL(nfsstatsv1.lookupcache_hits);
>> -			if (cnp->cn_nameiop != LOOKUP &&
>> -			    (flags & ISLASTCN))
>> -				cnp->cn_flags |= SAVENAME;
>>   			return (0);
>>   		}
>>   		cache_purge(newvp);
>> @@ -1372,7 +1365,6 @@ nfs_lookup(struct vop_lookup_args *ap)
>>   			 */
>>   			if (mp->mnt_flag & MNT_RDONLY)
>>   				return (EROFS);
>> -			cnp->cn_flags |= SAVENAME;
>>   			return (EJUSTRETURN);
>>   		}
>>
>> @@ -1428,7 +1420,6 @@ nfs_lookup(struct vop_lookup_args *ap)
>>   		if (attrflag)
>>   			(void) nfscl_loadattrcache(&newvp, &nfsva, NULL, 0, 1);
>>   		*vpp = newvp;
>> -		cnp->cn_flags |= SAVENAME;
>>   		return (0);
>>   	}
>>
>> @@ -1513,8 +1504,6 @@ nfs_lookup(struct vop_lookup_args *ap)
>>   			NFSUNLOCKNODE(np);
>>   		}
>>   	}
>> -	if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
>> -		cnp->cn_flags |= SAVENAME;
>>   	if ((cnp->cn_flags & MAKEENTRY) && dvp != newvp &&
>>   	    (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN)) &&
>>   	    attrflag != 0 && (newvp->v_type != VDIR || dattrflag != 0))
>> @@ -1881,7 +1870,6 @@ nfs_remove(struct vop_remove_args *ap)
>>   	int error = 0;
>>   	struct vattr vattr;
>>
>> -	KASSERT((cnp->cn_flags & HASBUF) != 0, ("nfs_remove: no name"));
>>   	KASSERT(vrefcnt(vp) > 0, ("nfs_remove: bad v_usecount"));
>>   	if (vp->v_type == VDIR)
>>   		error = EPERM;
>> @@ -1994,8 +1982,6 @@ nfs_rename(struct vop_rename_args *ap)
>>   	struct nfsv4node *newv4 = NULL;
>>   	int error;
>>
>> -	KASSERT((tcnp->cn_flags & HASBUF) != 0 &&
>> -	    (fcnp->cn_flags & HASBUF) != 0, ("nfs_rename: no name"));
>>   	/* Check for cross-device rename */
>>   	if ((fvp->v_mount != tdvp->v_mount) ||
>>   	    (tvp && (fvp->v_mount != tvp->v_mount))) {
>> diff --git a/sys/fs/nfsserver/nfs_nfsdport.c
>> b/sys/fs/nfsserver/nfs_nfsdport.c
>> index 9fc475ac7ecb..8e15237bc10c 100644
>> --- a/sys/fs/nfsserver/nfs_nfsdport.c
>> +++ b/sys/fs/nfsserver/nfs_nfsdport.c
>> @@ -686,8 +686,6 @@ nfsvno_namei(struct nfsrv_descript *nd, struct
>> nameidata *ndp,
>>   		 * termination occurs if no symlink encountered.
>>   		 */
>>   		if ((cnp->cn_flags & ISSYMLINK) == 0) {
>> -			if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0)
>> -				nfsvno_relpathbuf(ndp);
>>   			if (ndp->ni_vp && !lockleaf)
>>   				NFSVOPUNLOCK(ndp->ni_vp);
>>   			break;
>> @@ -796,7 +794,7 @@ nfsvno_setpathbuf(struct nameidata *ndp, char **bufpp,
>> u_long **hashpp)
>>   {
>>   	struct componentname *cnp = &ndp->ni_cnd;
>>
>> -	cnp->cn_flags |= (NOMACCHECK | HASBUF);
>> +	cnp->cn_flags |= (NOMACCHECK);
>>   	cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
>>   	if (hashpp != NULL)
>>   		*hashpp = NULL;
>> @@ -810,10 +808,8 @@ void
>>   nfsvno_relpathbuf(struct nameidata *ndp)
>>   {
>>
>> -	if ((ndp->ni_cnd.cn_flags & HASBUF) == 0)
>> -		panic("nfsrelpath");
>>   	uma_zfree(namei_zone, ndp->ni_cnd.cn_pnbuf);
>> -	ndp->ni_cnd.cn_flags &= ~HASBUF;
>> +	ndp->ni_cnd.cn_pnbuf = NULL;
>>   }
>>
>>   /*
>> @@ -1478,8 +1474,7 @@ nfsvno_removesub(struct nameidata *ndp, int is_v4,
>> struct ucred *cred,
>>   	else
>>   		vput(ndp->ni_dvp);
>>   	vput(vp);
>> -	if ((ndp->ni_cnd.cn_flags & SAVENAME) != 0)
>> -		nfsvno_relpathbuf(ndp);
>> +	nfsvno_relpathbuf(ndp);
>>   	NFSEXITCODE(error);
>>   	return (error);
>>   }
>> @@ -1519,8 +1514,7 @@ out:
>>   	else
>>   		vput(ndp->ni_dvp);
>>   	vput(vp);
>> -	if ((ndp->ni_cnd.cn_flags & SAVENAME) != 0)
>> -		nfsvno_relpathbuf(ndp);
>> +	nfsvno_relpathbuf(ndp);
>>   	NFSEXITCODE(error);
>>   	return (error);
>>   }
>> @@ -1939,8 +1933,7 @@ nfsvno_open(struct nfsrv_descript *nd, struct
>> nameidata *ndp,
>>   			}
>>   		}
>>   	} else {
>> -		if (ndp->ni_cnd.cn_flags & HASBUF)
>> -			nfsvno_relpathbuf(ndp);
>> +		nfsvno_relpathbuf(ndp);
>>   		if (ndp->ni_startdir && create == NFSV4OPEN_CREATE) {
>>   			vrele(ndp->ni_startdir);
>>   			if (ndp->ni_dvp == ndp->ni_vp)
>> @@ -4578,7 +4571,7 @@ nfsrv_dsremove(struct vnode *dvp, char *fname,
>> struct ucred *tcred,
>>   	named.ni_cnd.cn_nameiop = DELETE;
>>   	named.ni_cnd.cn_lkflags = LK_EXCLUSIVE | LK_RETRY;
>>   	named.ni_cnd.cn_cred = tcred;
>> -	named.ni_cnd.cn_flags = ISLASTCN | LOCKPARENT | LOCKLEAF | SAVENAME;
>> +	named.ni_cnd.cn_flags = ISLASTCN | LOCKPARENT | LOCKLEAF;
>>   	nfsvno_setpathbuf(&named, &bufp, &hashp);
>>   	named.ni_cnd.cn_nameptr = bufp;
>>   	named.ni_cnd.cn_namelen = strlen(fname);
>> @@ -6351,7 +6344,7 @@ nfsrv_pnfslookupds(struct vnode *vp, struct vnode
>> *dvp, struct pnfsdsfile *pf,
>>   	named.ni_cnd.cn_nameiop = LOOKUP;
>>   	named.ni_cnd.cn_lkflags = LK_SHARED | LK_RETRY;
>>   	named.ni_cnd.cn_cred = tcred;
>> -	named.ni_cnd.cn_flags = ISLASTCN | LOCKPARENT | LOCKLEAF | SAVENAME;
>> +	named.ni_cnd.cn_flags = ISLASTCN | LOCKPARENT | LOCKLEAF;
>>   	nfsvno_setpathbuf(&named, &bufp, &hashp);
>>   	named.ni_cnd.cn_nameptr = bufp;
>>   	named.ni_cnd.cn_namelen = strlen(pf->dsf_filename);
>> diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c
>> b/sys/fs/nfsserver/nfs_nfsdserv.c
>> index db1075596b91..23360f9e3909 100644
>> --- a/sys/fs/nfsserver/nfs_nfsdserv.c
>> +++ b/sys/fs/nfsserver/nfs_nfsdserv.c
>> @@ -1360,7 +1360,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int
>> isdgram,
>>   		case NFFIFO:
>>   			break;
>>   		case NFDIR:
>> -			cnflags = (LOCKPARENT | SAVENAME);
>> +			cnflags = LOCKPARENT;
>>   			break;
>>   		default:
>>   			nd->nd_repstat = NFSERR_BADTYPE;
>> @@ -1823,8 +1823,7 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
>>   				NFSVOPUNLOCK(dp);
>>   		}
>>   	}
>> -	NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
>> -	    LOCKPARENT | SAVENAME | NOCACHE);
>> +	NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, LOCKPARENT |
>> NOCACHE);
>>   	if (!nd->nd_repstat) {
>>   		nfsvno_setpathbuf(&named, &bufp, &hashp);
>>   		error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
>> @@ -2018,8 +2017,7 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, __unused int
>> isdgram,
>>   		nfsrv_wcc(nd, dirfor_ret, &dirfor, diraft_ret, &diraft);
>>   		goto out;
>>   	}
>> -	NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
>> -	    LOCKPARENT | SAVENAME | NOCACHE);
>> +	NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, LOCKPARENT |
>> NOCACHE);
>>   	nfsvno_setpathbuf(&named, &bufp, &hashp);
>>   	error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
>>   	if (error)
>> diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c
>> index 8df399b392f9..044745111543 100644
>> --- a/sys/fs/smbfs/smbfs_vnops.c
>> +++ b/sys/fs/smbfs/smbfs_vnops.c
>> @@ -1241,8 +1241,6 @@ smbfs_lookup(ap)
>>   		   killit = 1;
>>   		else if (error == 0
>>   	     /*    && vattr.va_ctime.tv_sec == VTOSMB(vp)->n_ctime*/) {
>> -		     if (nameiop != LOOKUP && islastcn)
>> -			     cnp->cn_flags |= SAVENAME;
>>   		     SMBVDEBUG("use cached vnode\n");
>>   		     return (0);
>>   		}
>> @@ -1296,7 +1294,6 @@ smbfs_lookup(ap)
>>   			error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
>>   			if (error)
>>   				goto out;
>> -			cnp->cn_flags |= SAVENAME;
>>   			error = EJUSTRETURN;
>>   			goto out;
>>   		}
>> @@ -1321,7 +1318,6 @@ smbfs_lookup(ap)
>>   		if (error)
>>   			goto out;
>>   		*vpp = vp;
>> -		cnp->cn_flags |= SAVENAME;
>>   		goto out;
>>   	}
>>   	if (nameiop == RENAME && islastcn) {
>> @@ -1336,7 +1332,6 @@ smbfs_lookup(ap)
>>   		if (error)
>>   			goto out;
>>   		*vpp = vp;
>> -		cnp->cn_flags |= SAVENAME;
>>   		goto out;
>>   	}
>>   	if (flags & ISDOTDOT) {
>> diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
>> index 7ec5f9bf3ffa..82036a35b4f0 100644
>> --- a/sys/fs/tmpfs/tmpfs_subr.c
>> +++ b/sys/fs/tmpfs/tmpfs_subr.c
>> @@ -1051,7 +1051,6 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode
>> **vpp, struct vattr *vap,
>>   	struct tmpfs_node *parent;
>>
>>   	ASSERT_VOP_ELOCKED(dvp, "tmpfs_alloc_file");
>> -	MPASS(cnp->cn_flags & HASBUF);
>>
>>   	tmp = VFS_TO_TMPFS(dvp->v_mount);
>>   	dnode = VP_TO_TMPFS_DIR(dvp);
>> diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
>> index bdad78f66ea5..8077689caeac 100644
>> --- a/sys/fs/tmpfs/tmpfs_vnops.c
>> +++ b/sys/fs/tmpfs/tmpfs_vnops.c
>> @@ -140,12 +140,6 @@ tmpfs_lookup1(struct vnode *dvp, struct vnode **vpp,
>> struct componentname *cnp)
>>   				if (error != 0)
>>   					goto out;
>>
>> -				/*
>> -				 * Keep the component name in the buffer for
>> -				 * future uses.
>> -				 */
>> -				cnp->cn_flags |= SAVENAME;
>> -
>>   				error = EJUSTRETURN;
>>   			} else
>>   				error = ENOENT;
>> @@ -199,7 +193,6 @@ tmpfs_lookup1(struct vnode *dvp, struct vnode **vpp,
>> struct componentname *cnp)
>>   					*vpp = NULL;
>>   					goto out;
>>   				}
>> -				cnp->cn_flags |= SAVENAME;
>>   			} else {
>>   				error = tmpfs_alloc_vp(dvp->v_mount, tnode,
>>   				    cnp->cn_lkflags, vpp);
>> @@ -778,7 +771,6 @@ tmpfs_link(struct vop_link_args *v)
>>   	struct tmpfs_node *node;
>>
>>   	MPASS(VOP_ISLOCKED(dvp));
>> -	MPASS(cnp->cn_flags & HASBUF);
>>   	MPASS(dvp != vp); /* XXX When can this be false? */
>>   	node = VP_TO_TMPFS_NODE(vp);
>>
>> @@ -971,8 +963,6 @@ tmpfs_rename(struct vop_rename_args *v)
>>
>>   	MPASS(VOP_ISLOCKED(tdvp));
>>   	MPASS(IMPLIES(tvp != NULL, VOP_ISLOCKED(tvp)));
>> -	MPASS(fcnp->cn_flags & HASBUF);
>> -	MPASS(tcnp->cn_flags & HASBUF);
>>
>>   	want_seqc_end = false;
>>
>> diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c
>> index a3a5feef3291..ac00cc1bc093 100644
>> --- a/sys/fs/unionfs/union_subr.c
>> +++ b/sys/fs/unionfs/union_subr.c
>> @@ -666,7 +666,7 @@ unionfs_relookup(struct vnode *dvp, struct vnode
>> **vpp,
>>   	cn->cn_namelen = pathlen;
>>   	cn->cn_pnbuf = path;
>>   	cn->cn_nameiop = nameiop;
>> -	cn->cn_flags = (LOCKPARENT | LOCKLEAF | HASBUF | SAVENAME | ISLASTCN);
>> +	cn->cn_flags = (LOCKPARENT | LOCKLEAF | ISLASTCN);
>>   	cn->cn_lkflags = LK_EXCLUSIVE;
>>   	cn->cn_cred = cnp->cn_cred;
>>   	cn->cn_nameptr = cn->cn_pnbuf;
>> @@ -686,10 +686,6 @@ unionfs_relookup(struct vnode *dvp, struct vnode
>> **vpp,
>>   	} else
>>   		vrele(dvp);
>>
>> -	KASSERT((cn->cn_flags & HASBUF) != 0,
>> -	    ("%s: HASBUF cleared", __func__));
>> -	KASSERT((cn->cn_flags & SAVENAME) != 0,
>> -	    ("%s: SAVENAME cleared", __func__));
>>   	KASSERT(cn->cn_pnbuf == path, ("%s: cn_pnbuf changed", __func__));
>>
>>   	return (error);
>> @@ -716,8 +712,6 @@ unionfs_relookup_for_create(struct vnode *dvp, struct
>> componentname *cnp,
>>   	udvp = UNIONFSVPTOUPPERVP(dvp);
>>   	vp = NULLVP;
>>
>> -	KASSERT((cnp->cn_flags & HASBUF) != 0,
>> -	    ("%s called without HASBUF", __func__));
>>   	error = unionfs_relookup(udvp, &vp, cnp, &cn, td, cnp->cn_nameptr,
>>   	    cnp->cn_namelen, CREATE);
>>   	if (error)
>> @@ -752,8 +746,6 @@ unionfs_relookup_for_delete(struct vnode *dvp, struct
>> componentname *cnp,
>>   	udvp = UNIONFSVPTOUPPERVP(dvp);
>>   	vp = NULLVP;
>>
>> -	KASSERT((cnp->cn_flags & HASBUF) != 0,
>> -	    ("%s called without HASBUF", __func__));
>>   	error = unionfs_relookup(udvp, &vp, cnp, &cn, td, cnp->cn_nameptr,
>>   	    cnp->cn_namelen, DELETE);
>>   	if (error)
>> @@ -788,8 +780,6 @@ unionfs_relookup_for_rename(struct vnode *dvp, struct
>> componentname *cnp,
>>   	udvp = UNIONFSVPTOUPPERVP(dvp);
>>   	vp = NULLVP;
>>
>> -	KASSERT((cnp->cn_flags & HASBUF) != 0,
>> -	    ("%s called without HASBUF", __func__));
>>   	error = unionfs_relookup(udvp, &vp, cnp, &cn, td, cnp->cn_nameptr,
>>   	    cnp->cn_namelen, RENAME);
>>   	if (error)
>> @@ -1020,8 +1010,7 @@ unionfs_vn_create_on_upper(struct vnode **vpp,
>> struct vnode *udvp,
>>   	nd.ni_cnd.cn_namelen = unp->un_pathlen;
>>   	nd.ni_cnd.cn_pnbuf = unp->un_path;
>>   	nd.ni_cnd.cn_nameiop = CREATE;
>> -	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | HASBUF | SAVENAME |
>> -	    ISLASTCN;
>> +	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | ISLASTCN;
>>   	nd.ni_cnd.cn_lkflags = LK_EXCLUSIVE;
>>   	nd.ni_cnd.cn_cred = cred;
>>   	nd.ni_cnd.cn_nameptr = nd.ni_cnd.cn_pnbuf;
>> @@ -1061,10 +1050,6 @@ unionfs_vn_create_on_upper_free_out1:
>>   	VOP_UNLOCK(udvp);
>>
>>   unionfs_vn_create_on_upper_free_out2:
>> -	KASSERT((nd.ni_cnd.cn_flags & HASBUF) != 0,
>> -	    ("%s: HASBUF cleared", __func__));
>> -	KASSERT((nd.ni_cnd.cn_flags & SAVENAME) != 0,
>> -	    ("%s: SAVENAME cleared", __func__));
>>   	KASSERT(nd.ni_cnd.cn_pnbuf == unp->un_path,
>>   	    ("%s: cn_pnbuf changed", __func__));
>>
>> @@ -1290,8 +1275,7 @@ unionfs_check_rmdir(struct vnode *vp, struct ucred
>> *cred, struct thread *td)
>>   			cn.cn_pnbuf = NULL;
>>   			cn.cn_nameptr = dp->d_name;
>>   			cn.cn_nameiop = LOOKUP;
>> -			cn.cn_flags = LOCKPARENT | LOCKLEAF | SAVENAME |
>> -			    RDONLY | ISLASTCN;
>> +			cn.cn_flags = LOCKPARENT | LOCKLEAF | RDONLY | ISLASTCN;
>>   			cn.cn_lkflags = LK_EXCLUSIVE;
>>   			cn.cn_cred = cred;
>>
>> @@ -1312,8 +1296,7 @@ unionfs_check_rmdir(struct vnode *vp, struct ucred
>> *cred, struct thread *td)
>>   			 * If it has no exist/whiteout entry in upper,
>>   			 * directory is not empty.
>>   			 */
>> -			cn.cn_flags = LOCKPARENT | LOCKLEAF | SAVENAME |
>> -			    RDONLY | ISLASTCN;
>> +			cn.cn_flags = LOCKPARENT | LOCKLEAF | RDONLY | ISLASTCN;
>>   			lookuperr = VOP_LOOKUP(uvp, &tvp, &cn);
>>
>>   			if (!lookuperr)
>> diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c
>> index 8403805a99d4..04d788959892 100644
>> --- a/sys/fs/unionfs/union_vnops.c
>> +++ b/sys/fs/unionfs/union_vnops.c
>> @@ -348,10 +348,6 @@ unionfs_lookup_cleanup:
>>
>>   unionfs_lookup_return:
>>
>> -	/* Ensure subsequent vnops will get a valid pathname buffer. */
>> -	if (nameiop != LOOKUP && (error == 0 || error == EJUSTRETURN))
>> -		cnp->cn_flags |= SAVENAME;
>> -
>>   	UNIONFS_INTERNAL_DEBUG("unionfs_lookup: leave (%d)\n", error);
>>
>>   	return (error);
>> @@ -1205,11 +1201,6 @@ unionfs_rename(struct vop_rename_args *ap)
>>   	rtvp = tvp;
>>   	needrelookup = 0;
>>
>> -#ifdef DIAGNOSTIC
>> -	if (!(fcnp->cn_flags & HASBUF) || !(tcnp->cn_flags & HASBUF))
>> -		panic("unionfs_rename: no name");
>> -#endif
>> -
>>   	/* check for cross device rename */
>>   	if (fvp->v_mount != tdvp->v_mount ||
>>   	    (tvp != NULLVP && fvp->v_mount != tvp->v_mount)) {
>> diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
>> index 364c10987ea6..cb45d18fbb85 100644
>> --- a/sys/kern/kern_exec.c
>> +++ b/sys/kern/kern_exec.c
>> @@ -474,7 +474,7 @@ interpret:
>>   		 * pointer in ni_vp among other things.
>>   		 */
>>   		NDINIT(&nd, LOOKUP, ISOPEN | LOCKLEAF | LOCKSHARED | FOLLOW |
>> -		    SAVENAME | AUDITVNODE1 | WANTPARENT, UIO_SYSSPACE,
>> +		    AUDITVNODE1 | WANTPARENT, UIO_SYSSPACE,
>>   		    args->fname);
>>
>>   		error = namei(&nd);
>> diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c
>> index 745c1174638e..29c7bcdd4289 100644
>> --- a/sys/kern/uipc_mqueue.c
>> +++ b/sys/kern/uipc_mqueue.c
>> @@ -941,7 +941,6 @@ mqfs_lookupx(struct vop_cachedlookup_args *ap)
>>   		error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
>>   		if (error)
>>   			return (error);
>> -		cnp->cn_flags |= SAVENAME;
>>   		return (EJUSTRETURN);
>>   	}
>>   	return (ENOENT);
>> @@ -997,8 +996,6 @@ mqfs_create(struct vop_create_args *ap)
>>   	if (mq == NULL)
>>   		return (EAGAIN);
>>   	sx_xlock(&mqfs->mi_lock);
>> -	if ((cnp->cn_flags & HASBUF) == 0)
>> -		panic("%s: no name", __func__);
>>   	pn = mqfs_create_file(pd, cnp->cn_nameptr, cnp->cn_namelen,
>>   		cnp->cn_cred, ap->a_vap->va_mode);
>>   	if (pn == NULL) {
>> @@ -1492,8 +1489,6 @@ mqfs_mkdir(struct vop_mkdir_args *ap)
>>   	if (pd->mn_type != mqfstype_root && pd->mn_type != mqfstype_dir)
>>   		return (ENOTDIR);
>>   	sx_xlock(&mqfs->mi_lock);
>> -	if ((cnp->cn_flags & HASBUF) == 0)
>> -		panic("%s: no name", __func__);
>>   	pn = mqfs_create_dir(pd, cnp->cn_nameptr, cnp->cn_namelen,
>>   		ap->a_vap->cn_cred, ap->a_vap->va_mode);
>>   	if (pn != NULL)
>> diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
>> index 2b78c3e51907..1a4d2d5adc0a 100644
>> --- a/sys/kern/uipc_usrreq.c
>> +++ b/sys/kern/uipc_usrreq.c
>> @@ -593,7 +593,7 @@ uipc_bindat(int fd, struct socket *so, struct sockaddr
>> *nam, struct thread *td)
>>   	buf[namelen] = 0;
>>
>>   restart:
>> -	NDINIT_ATRIGHTS(&nd, CREATE, NOFOLLOW | LOCKPARENT | SAVENAME |
>> NOCACHE,
>> +	NDINIT_ATRIGHTS(&nd, CREATE, NOFOLLOW | LOCKPARENT | NOCACHE,
>>   	    UIO_SYSSPACE, buf, fd, cap_rights_init_one(&rights, CAP_BINDAT));
>>   /* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */
>>   	error = namei(&nd);
>> @@ -1919,9 +1919,9 @@ unp_connectat(int fd, struct socket *so, struct
>> sockaddr *nam,
>>   	else
>>   		vp = nd.ni_vp;
>>   	ASSERT_VOP_LOCKED(vp, "unp_connect");
>> -	NDFREE_NOTHING(&nd);
>>   	if (error)
>>   		goto bad;
>> +	NDFREE_PNBUF(&nd);
>>
>>   	if (vp->v_type != VSOCK) {
>>   		error = ENOTSOCK;
>> diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
>> index 9e25d6f8fefb..5f72506549bd 100644
>> --- a/sys/kern/vfs_cache.c
>> +++ b/sys/kern/vfs_cache.c
>> @@ -3134,7 +3134,7 @@ kern___realpathat(struct thread *td, int fd, const
>> char *path, char *buf,
>>
>>   	if (flags != 0)
>>   		return (EINVAL);
>> -	NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | SAVENAME | WANTPARENT |
>> AUDITVNODE1,
>> +	NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | WANTPARENT | AUDITVNODE1,
>>   	    pathseg, path, fd, &cap_fstat_rights);
>>   	if ((error = namei(&nd)) != 0)
>>   		return (error);
>> @@ -3600,9 +3600,9 @@ vn_fullpath_any(struct vnode *vp, struct vnode
>> *rdir, char *buf, char **retbuf,
>>   /*
>>    * Resolve an arbitrary vnode to a pathname (taking care of hardlinks).
>>    *
>> - * Since the namecache does not track hardlinks, the caller is
>> - * expected to first look up the target vnode with SAVENAME |
>> - * WANTPARENT flags passed to namei to get dvp and vp.
>> + * Since the namecache does not track hardlinks, the caller is expected
>> to
>> + * first look up the target vnode with WANTPARENT flag passed to namei to
>> get
>> + * dvp and vp.
>>    *
>>    * Then we have 2 cases:
>>    * - if the found vnode is a directory, the path can be constructed just
>> by
>> @@ -3928,7 +3928,6 @@ struct cache_fpl {
>>   	enum cache_fpl_status status:8;
>>   	bool in_smr;
>>   	bool fsearch;
>> -	bool savename;
>>   	struct pwd **pwd;
>>   #ifdef INVARIANTS
>>   	struct cache_fpl_debug debug;
>> @@ -3951,10 +3950,8 @@ cache_fpl_cleanup_cnp(struct componentname *cnp)
>>   {
>>
>>   	uma_zfree(namei_zone, cnp->cn_pnbuf);
>> -#ifdef DIAGNOSTIC
>>   	cnp->cn_pnbuf = NULL;
>>   	cnp->cn_nameptr = NULL;
>> -#endif
>>   }
>>
>>   static struct vnode *
>> @@ -4166,7 +4163,6 @@ cache_fpl_handled_error_impl(struct cache_fpl *fpl,
>> int error, int line)
>>   	fpl->line = line;
>>   	fpl->dvp = NULL;
>>   	fpl->tvp = NULL;
>> -	fpl->savename = false;
>>   	return (error);
>>   }
>>
>> @@ -4181,9 +4177,9 @@ cache_fpl_terminated(struct cache_fpl *fpl)
>>
>>   #define CACHE_FPL_SUPPORTED_CN_FLAGS \
>>   	(NC_NOMAKEENTRY | NC_KEEPPOSENTRY | LOCKLEAF | LOCKPARENT | WANTPARENT
>> | \
>> -	 FAILIFEXISTS | FOLLOW | EMPTYPATH | LOCKSHARED | SAVENAME | SAVESTART |
>> \
>> -	 WILLBEDIR | ISOPEN | NOMACCHECK | AUDITVNODE1 | AUDITVNODE2 |
>> NOCAPCHECK | \
>> -	 OPENREAD | OPENWRITE | WANTIOCTLCAPS)
>> +	 FAILIFEXISTS | FOLLOW | EMPTYPATH | LOCKSHARED | SAVESTART | WILLBEDIR
>> | \
>> +	 ISOPEN | NOMACCHECK | AUDITVNODE1 | AUDITVNODE2 | NOCAPCHECK | OPENREAD
>> | \
>> +	 OPENWRITE | WANTIOCTLCAPS)
>>
>>   #define CACHE_FPL_INTERNAL_CN_FLAGS \
>>   	(ISDOTDOT | MAKEENTRY | ISLASTCN)
>> @@ -4530,14 +4526,11 @@ cache_fplookup_final_modifying(struct cache_fpl
>> *fpl)
>>   	}
>>
>>   	fpl->tvp = tvp;
>> -	fpl->savename = (cnp->cn_flags & SAVENAME) != 0;
>>
>>   	if (tvp == NULL) {
>>   		if ((cnp->cn_flags & SAVESTART) != 0) {
>>   			ndp->ni_startdir = dvp;
>>   			vrefact(ndp->ni_startdir);
>> -			cnp->cn_flags |= SAVENAME;
>> -			fpl->savename = true;
>>   		}
>>   		MPASS(error == EJUSTRETURN);
>>   		if ((cnp->cn_flags & LOCKPARENT) == 0) {
>> @@ -4598,8 +4591,6 @@ cache_fplookup_final_modifying(struct cache_fpl
>> *fpl)
>>   	if ((cnp->cn_flags & SAVESTART) != 0) {
>>   		ndp->ni_startdir = dvp;
>>   		vrefact(ndp->ni_startdir);
>> -		cnp->cn_flags |= SAVENAME;
>> -		fpl->savename = true;
>>   	}
>>
>>   	return (cache_fpl_handled(fpl));
>> @@ -4944,9 +4935,6 @@ cache_fplookup_noentry(struct cache_fpl *fpl)
>>   	}
>>
>>   	fpl->tvp = tvp;
>> -	if (!fpl->savename) {
>> -		MPASS((cnp->cn_flags & SAVENAME) == 0);
>> -	}
>>
>>   	if (tvp == NULL) {
>>   		MPASS(error == EJUSTRETURN);
>> @@ -6080,7 +6068,6 @@ cache_fplookup(struct nameidata *ndp, enum
>> cache_fpl_status *status,
>>   #endif
>>   	fpl.nulchar = &cnp->cn_nameptr[ndp->ni_pathlen - 1];
>>   	fpl.fsearch = false;
>> -	fpl.savename = (cnp->cn_flags & SAVENAME) != 0;
>>   	fpl.tvp = NULL; /* for degenerate path handling */
>>   	fpl.pwd = pwdp;
>>   	pwd = pwd_get_smr();
>> @@ -6119,17 +6106,12 @@ out:
>>   	if (__predict_true(fpl.status == CACHE_FPL_STATUS_HANDLED)) {
>>   		MPASS(error != CACHE_FPL_FAILED);
>>   		if (error != 0) {
>> +			cache_fpl_cleanup_cnp(fpl.cnp);
>>   			MPASS(fpl.dvp == NULL);
>>   			MPASS(fpl.tvp == NULL);
>> -			MPASS(fpl.savename == false);
>>   		}
>>   		ndp->ni_dvp = fpl.dvp;
>>   		ndp->ni_vp = fpl.tvp;
>> -		if (fpl.savename) {
>> -			cnp->cn_flags |= HASBUF;
>> -		} else {
>> -			cache_fpl_cleanup_cnp(cnp);
>> -		}
>>   	}
>>   	return (error);
>>   }
>> diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
>> index 79c7fd8365fa..7fac64ff1b38 100644
>> --- a/sys/kern/vfs_lookup.c
>> +++ b/sys/kern/vfs_lookup.c
>> @@ -75,11 +75,12 @@ __FBSDID("$FreeBSD$");
>>   #undef NAMEI_DIAGNOSTIC
>>
>>   #ifdef INVARIANTS
>> -static void NDVALIDATE(struct nameidata *);
>> -#else
>> -#define NDVALIDATE(ndp) do { } while (0)
>> +static void NDVALIDATE_impl(struct nameidata *, int);
>>   #endif
>>
>> +#define NDVALIDATE(ndp) NDVALIDATE_impl(ndp, __LINE__)
>> +
>> +
>>   SDT_PROVIDER_DEFINE(vfs);
>>   SDT_PROBE_DEFINE4(vfs, namei, lookup, entry, "struct vnode *", "char
>> *",
>>       "unsigned long", "bool");
>> @@ -260,10 +261,8 @@ namei_cleanup_cnp(struct componentname *cnp)
>>   {
>>
>>   	uma_zfree(namei_zone, cnp->cn_pnbuf);
>> -#ifdef DIAGNOSTIC
>>   	cnp->cn_pnbuf = NULL;
>>   	cnp->cn_nameptr = NULL;
>> -#endif
>>   }
>>
>>   static int
>> @@ -439,7 +438,6 @@ namei_emptypath(struct nameidata *ndp)
>>   	ndp->ni_resflags |= NIRES_EMPTYPATH;
>>   	error = namei_setup(ndp, &dp, &pwd);
>>   	if (error != 0) {
>> -		namei_cleanup_cnp(cnp);
>>   		goto errout;
>>   	}
>>
>> @@ -447,7 +445,6 @@ namei_emptypath(struct nameidata *ndp)
>>   	 * Usecount on dp already provided by namei_setup.
>>   	 */
>>   	ndp->ni_vp = dp;
>> -	namei_cleanup_cnp(cnp);
>>   	pwd_drop(pwd);
>>   	NDVALIDATE(ndp);
>>   	if ((cnp->cn_flags & LOCKLEAF) != 0) {
>> @@ -464,6 +461,7 @@ namei_emptypath(struct nameidata *ndp)
>>
>> *** 562 LINES SKIPPED ***
>


-- 
Mateusz Guzik <mjguzik gmail.com>