git: 8f874e92ebc9 - main - vfs: make relookup take an additional argument

From: Mateusz Guzik <mjg_at_FreeBSD.org>
Date: Mon, 19 Dec 2022 08:14:40 UTC
The branch main has been updated by mjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=8f874e92ebc9e75b5dd7935a042cf016be19fb38

commit 8f874e92ebc9e75b5dd7935a042cf016be19fb38
Author:     Mateusz Guzik <mjg@FreeBSD.org>
AuthorDate: 2022-11-10 01:45:13 +0000
Commit:     Mateusz Guzik <mjg@FreeBSD.org>
CommitDate: 2022-12-19 08:09:00 +0000

    vfs: make relookup take an additional argument
    
    instead of looking at SAVESTART
    
    This is a step towards removing the flag.
    
    Reviewed by:    mckusick
    Tested by:      pho
    Differential Revision:  https://reviews.freebsd.org/D34468
---
 sys/fs/ext2fs/ext2_vnops.c  |  4 ++--
 sys/fs/unionfs/union_subr.c | 18 +++++++++++-------
 sys/kern/vfs_lookup.c       |  9 +++++----
 sys/sys/namei.h             |  2 +-
 4 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/sys/fs/ext2fs/ext2_vnops.c b/sys/fs/ext2fs/ext2_vnops.c
index 5948cbd052e3..a7da8249ab4d 100644
--- a/sys/fs/ext2fs/ext2_vnops.c
+++ b/sys/fs/ext2fs/ext2_vnops.c
@@ -910,7 +910,7 @@ abortit:
 		if (error)
 			goto out;
 		VREF(tdvp);
-		error = vfs_relookup(tdvp, &tvp, tcnp);
+		error = vfs_relookup(tdvp, &tvp, tcnp, true);
 		if (error)
 			goto out;
 		vrele(tdvp);
@@ -1036,7 +1036,7 @@ abortit:
 	fcnp->cn_flags &= ~MODMASK;
 	fcnp->cn_flags |= LOCKPARENT | LOCKLEAF;
 	VREF(fdvp);
-	error = vfs_relookup(fdvp, &fvp, fcnp);
+	error = vfs_relookup(fdvp, &fvp, fcnp, true);
 	if (error == 0)
 		vrele(fdvp);
 	if (fvp != NULL) {
diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c
index 0b9e8fde4b6a..29e18b355f68 100644
--- a/sys/fs/unionfs/union_subr.c
+++ b/sys/fs/unionfs/union_subr.c
@@ -662,6 +662,7 @@ unionfs_relookup(struct vnode *dvp, struct vnode **vpp,
     char *path, int pathlen, u_long nameiop)
 {
 	int error;
+	bool refstart;
 
 	cn->cn_namelen = pathlen;
 	cn->cn_pnbuf = path;
@@ -671,17 +672,20 @@ unionfs_relookup(struct vnode *dvp, struct vnode **vpp,
 	cn->cn_cred = cnp->cn_cred;
 	cn->cn_nameptr = cn->cn_pnbuf;
 
-	if (nameiop == DELETE)
-		cn->cn_flags |= (cnp->cn_flags & (DOWHITEOUT | SAVESTART));
-	else if (RENAME == nameiop)
-		cn->cn_flags |= (cnp->cn_flags & SAVESTART);
-	else if (nameiop == CREATE)
+	refstart = false;
+	if (nameiop == DELETE) {
+		cn->cn_flags |= (cnp->cn_flags & DOWHITEOUT);
+		refstart = (cnp->cn_flags & SAVESTART) != 0;
+	} else if (RENAME == nameiop) {
+		refstart = (cnp->cn_flags & SAVESTART) != 0;
+	} else if (nameiop == CREATE) {
 		cn->cn_flags |= NOCACHE;
+	}
 
 	vref(dvp);
 	VOP_UNLOCK(dvp);
 
-	if ((error = vfs_relookup(dvp, vpp, cn))) {
+	if ((error = vfs_relookup(dvp, vpp, cn, refstart))) {
 		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
 	} else
 		vrele(dvp);
@@ -1017,7 +1021,7 @@ unionfs_vn_create_on_upper(struct vnode **vpp, struct vnode *udvp,
 	NDPREINIT(&nd);
 
 	vref(udvp);
-	if ((error = vfs_relookup(udvp, &vp, &nd.ni_cnd)) != 0)
+	if ((error = vfs_relookup(udvp, &vp, &nd.ni_cnd, false)) != 0)
 		goto unionfs_vn_create_on_upper_free_out2;
 	vrele(udvp);
 
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
index ac5617616e30..a5f73676d308 100644
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -1435,7 +1435,8 @@ bad_unlocked:
  *    Used by lookup to re-acquire things.
  */
 int
-vfs_relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
+vfs_relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
+    bool refstart)
 {
 	struct vnode *dp = NULL;		/* the directory we are searching */
 	int rdonly;			/* lookup read-only flag bit */
@@ -1479,7 +1480,7 @@ vfs_relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
 			VOP_UNLOCK(dp);
 		*vpp = dp;
 		/* XXX This should probably move to the top of function. */
-		if (cnp->cn_flags & SAVESTART)
+		if (refstart)
 			panic("lookup: SAVESTART");
 		return (0);
 	}
@@ -1506,7 +1507,7 @@ vfs_relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
 			goto bad;
 		}
 		/* ASSERT(dvp == ndp->ni_startdir) */
-		if (cnp->cn_flags & SAVESTART)
+		if (refstart)
 			VREF(dvp);
 		if ((cnp->cn_flags & LOCKPARENT) == 0)
 			VOP_UNLOCK(dp);
@@ -1544,7 +1545,7 @@ vfs_relookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
 	    ("relookup: symlink found.\n"));
 
 	/* ASSERT(dvp == ndp->ni_startdir) */
-	if (cnp->cn_flags & SAVESTART)
+	if (refstart)
 		VREF(dvp);
 
 	if ((cnp->cn_flags & LOCKLEAF) == 0)
diff --git a/sys/sys/namei.h b/sys/sys/namei.h
index d527d4a3bed0..eafb23ed0929 100644
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -293,7 +293,7 @@ do {										\
 int	namei(struct nameidata *ndp);
 int	vfs_lookup(struct nameidata *ndp);
 int	vfs_relookup(struct vnode *dvp, struct vnode **vpp,
-	    struct componentname *cnp);
+	    struct componentname *cnp, bool refstart);
 #endif
 
 /*