Subject: ufs-ism in lookup(9)
To: None <tech-kern@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: tech-kern
Date: 03/20/2004 16:13:00
--NextPart-20040320160134-0151501
Content-Type: Text/Plain; charset=us-ascii

hi,

currently, for some vnode operations, lookup(9) disable caching
for the benefit of some filesystems including ufs.

>	if (cnp->cn_nameiop == DELETE ||
>	    (wantparent && cnp->cn_nameiop != CREATE))
>		docache = 0;

however, due to this, our nfs client issues LOOKUP rpcs which isn't
really needed in the most cases.

while it could be workarounded in nfs code,
i think it's better to push this ufs-ism into each filesystems
which really need it.

i'll commit the attached diffs if no one objects.

YAMAMOTO Takashi

--NextPart-20040320160134-0151501
Content-Type: Text/Plain; charset=us-ascii
Content-Disposition: attachment; filename="lookup.diff"

Index: kern/vfs_lookup.c
===================================================================
--- kern/vfs_lookup.c	(revision 462)
+++ kern/vfs_lookup.c	(working copy)
@@ -336,9 +336,6 @@ lookup(ndp)
 	 */
 	wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT);
 	docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE;
-	if (cnp->cn_nameiop == DELETE ||
-	    (wantparent && cnp->cn_nameiop != CREATE))
-		docache = 0;
 	rdonly = cnp->cn_flags & RDONLY;
 	ndp->ni_dvp = NULL;
 	cnp->cn_flags &= ~ISSYMLINK;
Index: ufs/ext2fs/ext2fs_lookup.c
===================================================================
--- ufs/ext2fs/ext2fs_lookup.c	(revision 266)
+++ ufs/ext2fs/ext2fs_lookup.c	(working copy)
@@ -289,8 +289,8 @@ ext2fs_lookup(v)
 	int flags = cnp->cn_flags;
 	int nameiop = cnp->cn_nameiop;
 	ino_t foundino;
-
 	int	dirblksize = VTOI(ap->a_dvp)->i_e2fs->e2fs_bsize;
+	boolean_t toremove;
 
 	bp = NULL;
 	slotoffset = -1;
@@ -305,8 +305,9 @@ ext2fs_lookup(v)
 	if ((error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)) != 0)
 		return (error);
 
-	if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
-	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
+	toremove = (flags & ISLASTCN) &&
+	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME);
+	if (toremove && (vdp->v_mount->mnt_flag & MNT_RDONLY))
 		return (EROFS);
 
 	/*
@@ -316,8 +317,13 @@ ext2fs_lookup(v)
 	 * check the name cache to see if the directory/name pair
 	 * we are looking for is known already.
 	 */
-	if ((error = cache_lookup(vdp, vpp, cnp)) >= 0)
-		return (error);
+	if (toremove) {
+		cache_purge1(vdp, cnp, 0);
+		cnp->cn_flags &= ~MAKEENTRY;
+	} else {
+		if ((error = cache_lookup(vdp, vpp, cnp)) >= 0)
+			return (error);
+	}
 
 	/*
 	 * Suppress search for slots unless creating
Index: ufs/ufs/ufs_lookup.c
===================================================================
--- ufs/ufs/ufs_lookup.c	(revision 599)
+++ ufs/ufs/ufs_lookup.c	(working copy)
@@ -133,6 +133,7 @@ ufs_lookup(v)
 	const int needswap = UFS_MPNEEDSWAP(ap->a_dvp->v_mount);
 	int dirblksiz = DIRBLKSIZ;
 	ino_t foundino;
+	boolean_t toremove;
 	if (UFS_MPISAPPLEUFS(ap->a_dvp->v_mount)) {
 		dirblksiz = APPLEUFS_DIRBLKSIZ;
 	}
@@ -155,8 +156,9 @@ ufs_lookup(v)
 	if ((error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)) != 0)
 		return (error);
 
-	if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
-	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
+	toremove = (flags & ISLASTCN) &&
+	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME);
+	if (toremove && (vdp->v_mount->mnt_flag & MNT_RDONLY))
 		return (EROFS);
 
 	/*
@@ -166,8 +168,13 @@ ufs_lookup(v)
 	 * check the name cache to see if the directory/name pair
 	 * we are looking for is known already.
 	 */
-	if ((error = cache_lookup(vdp, vpp, cnp)) >= 0)
-		return (error);
+	if (toremove) {
+		cache_purge1(vdp, cnp, 0);
+		cnp->cn_flags &= ~MAKEENTRY;
+	} else {
+		if ((error = cache_lookup(vdp, vpp, cnp)) >= 0)
+			return (error);
+	}
 
 	/*
 	 * Suppress search for slots unless creating
Index: nfs/nfs_vnops.c
===================================================================
--- nfs/nfs_vnops.c	(revision 640)
+++ nfs/nfs_vnops.c	(working copy)
@@ -1760,6 +1760,7 @@ nfs_remove(v)
 	PNBUF_PUT(cnp->cn_pnbuf);
 	if (!error && nfs_getattrcache(vp, &vattr) == 0 &&
 	    vattr.va_nlink == 1) {
+		cache_purge1(dvp, cnp, 0);
 		np->n_flag |= NREMOVED;
 	}
 	NFS_INVALIDATE_ATTRCACHE(np);
@@ -1872,11 +1873,11 @@ nfs_rename(v)
 
 	VN_KNOTE(fdvp, NOTE_WRITE);
 	VN_KNOTE(tdvp, NOTE_WRITE);
-	if (fvp->v_type == VDIR) {
-		if (tvp != NULL && tvp->v_type == VDIR)
-			cache_purge(tdvp);
-		cache_purge(fdvp);
-	}
+	if (fvp->v_type == VDIR)
+		cache_purge(fvp); /* we need to flush DOTDOT entry */
+	else
+		cache_purge1(fdvp, fcnp, 0);
+	cache_purge1(tdvp, tcnp, 0);
 out:
 	if (tdvp == tvp)
 		vrele(tdvp);
Index: fs/smbfs/smbfs_vnops.c
===================================================================
--- fs/smbfs/smbfs_vnops.c	(revision 599)
+++ fs/smbfs/smbfs_vnops.c	(working copy)
@@ -588,6 +588,8 @@ smbfs_remove(v)
 
 	VN_KNOTE(ap->a_vp, NOTE_DELETE);
 	VN_KNOTE(ap->a_dvp, NOTE_WRITE);
+	if (!error)
+		cache_purge1(dvp, cnp, 0);
 	if (dvp == vp)
 		vrele(vp);
 	else
@@ -616,7 +618,7 @@ smbfs_rename(v)
 	struct vnode *fdvp = ap->a_fdvp;
 	struct vnode *tdvp = ap->a_tdvp;
 	struct componentname *tcnp = ap->a_tcnp;
-/*	struct componentname *fcnp = ap->a_fcnp;*/
+	struct componentname *fcnp = ap->a_fcnp;
 	struct smb_cred scred;
 #ifdef notyet
 	u_int16_t flags = 6;
@@ -673,11 +675,11 @@ smbfs_rename(v)
 		VN_KNOTE(fvp, NOTE_RENAME);
 	}
 
-	if (fvp->v_type == VDIR) {
-		if (tvp != NULL && tvp->v_type == VDIR)
-			cache_purge(tdvp);
-		cache_purge(fdvp);
-	}
+	if (fvp->v_type == VDIR)
+		cache_purge(fvp); /* we need to flush DOTDOT entry */
+	else
+		cache_purge1(fdvp, fcnp, 0);
+	cache_purge1(tdvp, tcnp, 0);
 
 	smbfs_attr_cacheremove(fdvp);
 	smbfs_attr_cacheremove(tdvp);
Index: fs/msdosfs/msdosfs_lookup.c
===================================================================
--- fs/msdosfs/msdosfs_lookup.c	(revision 196)
+++ fs/msdosfs/msdosfs_lookup.c	(working copy)
@@ -116,6 +116,7 @@ msdosfs_lookup(v)
 	int wincnt = 1;
 	int chksum = -1, chksum_ok;
 	int olddos = 1;
+	boolean_t toremove;
 
 	cnp->cn_flags &= ~PDIRUNLOCK; /* XXX why this ?? */
 	flags = cnp->cn_flags;
@@ -140,8 +141,9 @@ msdosfs_lookup(v)
 	if ((error = VOP_ACCESS(vdp, VEXEC, cnp->cn_cred, cnp->cn_proc)) != 0)
 		return (error);
 
-	if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) &&
-	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
+	toremove = (flags & ISLASTCN) &&
+	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME);
+	if (toremove && (vdp->v_mount->mnt_flag & MNT_RDONLY))
 		return (EROFS);
 
 	/*
@@ -151,8 +153,13 @@ msdosfs_lookup(v)
 	 * check the name cache to see if the directory/name pair
 	 * we are looking for is known already.
 	 */
-	if ((error = cache_lookup(vdp, vpp, cnp)) >= 0)
-		return (error);
+	if (toremove) {
+		cache_purge1(vdp, cnp, 0);
+		cnp->cn_flags &= ~MAKEENTRY;
+	} else {
+		if ((error = cache_lookup(vdp, vpp, cnp)) >= 0)
+			return (error);
+	}
 
 	/*
 	 * If they are going after the . or .. entry in the root directory,

--NextPart-20040320160134-0151501--