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--