The VOP_LOOKUP() implementations for CREATE op do not put the name
into namecache, to avoid cache trashing when doing large operations. E.g., tar archive extraction is not usually followed by access to many of the files created. Right now, each VOP_LOOKUP() implementation explicitely knowns about this quirk and tests for both MAKEENTRY flag presence and op != CREATE to make the call to cache_enter(). Centralize the handling of the quirk into VFS, by deciding to cache only by MAKEENTRY flag in VOP. VFS now sets NOCACHE flag for CREATE namei() calls. Note that the change in semantic is backward-compatible and could be merged to the stable branch, and is compatible with non-changed third-party filesystems which correctly handle MAKEENTRY. Suggested by: Chris Torek <torek@pi-coral.com> Reviewed by: mckusick Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
This commit is contained in:
parent
9c75c3d4ba
commit
6c21f6edb8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=275897
@ -1548,7 +1548,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp,
|
||||
/*
|
||||
* Insert name into cache (as non-existent) if appropriate.
|
||||
*/
|
||||
if (error == ENOENT && (cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
|
||||
if (error == ENOENT && (cnp->cn_flags & MAKEENTRY) != 0)
|
||||
cache_enter(dvp, *vpp, cnp);
|
||||
/*
|
||||
* Insert name into cache if appropriate.
|
||||
|
@ -514,7 +514,7 @@ ext2_lookup_ino(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp
|
||||
/*
|
||||
* Insert name into cache (as non-existent) if appropriate.
|
||||
*/
|
||||
if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
|
||||
if ((cnp->cn_flags & MAKEENTRY) != 0)
|
||||
cache_enter(vdp, NULL, cnp);
|
||||
return (ENOENT);
|
||||
|
||||
|
@ -795,7 +795,7 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
|
||||
* caching...)
|
||||
*/
|
||||
#if 0
|
||||
if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) {
|
||||
if ((cnp->cn_flags & MAKEENTRY) != 0) {
|
||||
FS_DEBUG("inserting NULL into cache\n");
|
||||
cache_enter(dvp, NULL, cnp);
|
||||
}
|
||||
|
@ -416,7 +416,7 @@ msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp,
|
||||
* and 8.3 filenames. Hence, it may not invalidate all negative
|
||||
* entries if a file with this name is later created.
|
||||
*/
|
||||
if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
|
||||
if ((cnp->cn_flags & MAKEENTRY) != 0)
|
||||
cache_enter(vdp, *vpp, cnp);
|
||||
#endif
|
||||
return (ENOENT);
|
||||
|
@ -478,7 +478,7 @@ nandfs_lookup(struct vop_cachedlookup_args *ap)
|
||||
* the file might not be found and thus putting it into the namecache
|
||||
* might be seen as negative caching.
|
||||
*/
|
||||
if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
|
||||
if ((cnp->cn_flags & MAKEENTRY) != 0)
|
||||
cache_enter(dvp, *vpp, cnp);
|
||||
|
||||
return (error);
|
||||
|
@ -1184,8 +1184,7 @@ nfs_lookup(struct vop_lookup_args *ap)
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
|
||||
if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE &&
|
||||
dattrflag) {
|
||||
if ((cnp->cn_flags & MAKEENTRY) != 0 && dattrflag) {
|
||||
/*
|
||||
* Cache the modification time of the parent
|
||||
* directory from the post-op attributes in
|
||||
|
@ -994,7 +994,7 @@ nfsrvd_create(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
goto out;
|
||||
}
|
||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
|
||||
LOCKPARENT | LOCKLEAF | SAVESTART);
|
||||
LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE);
|
||||
nfsvno_setpathbuf(&named, &bufp, &hashp);
|
||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
|
||||
if (error)
|
||||
@ -1205,7 +1205,7 @@ nfsrvd_mknod(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, cnflags);
|
||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE, cnflags | NOCACHE);
|
||||
nfsvno_setpathbuf(&named, &bufp, &hashp);
|
||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
|
||||
if (error)
|
||||
@ -1658,7 +1658,7 @@ nfsrvd_link(struct nfsrv_descript *nd, int isdgram,
|
||||
}
|
||||
}
|
||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
|
||||
LOCKPARENT | SAVENAME);
|
||||
LOCKPARENT | SAVENAME | NOCACHE);
|
||||
if (!nd->nd_repstat) {
|
||||
nfsvno_setpathbuf(&named, &bufp, &hashp);
|
||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
|
||||
@ -1735,7 +1735,7 @@ nfsrvd_symlink(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
*vpp = NULL;
|
||||
NFSVNO_ATTRINIT(&nva);
|
||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
|
||||
LOCKPARENT | SAVESTART);
|
||||
LOCKPARENT | SAVESTART | NOCACHE);
|
||||
nfsvno_setpathbuf(&named, &bufp, &hashp);
|
||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
|
||||
if (!error && !nd->nd_repstat)
|
||||
@ -1853,7 +1853,7 @@ nfsrvd_mkdir(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
goto out;
|
||||
}
|
||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
|
||||
LOCKPARENT | SAVENAME);
|
||||
LOCKPARENT | SAVENAME | NOCACHE);
|
||||
nfsvno_setpathbuf(&named, &bufp, &hashp);
|
||||
error = nfsrv_parsename(nd, bufp, hashp, &named.ni_pathlen);
|
||||
if (error)
|
||||
@ -2782,7 +2782,7 @@ nfsrvd_open(struct nfsrv_descript *nd, __unused int isdgram,
|
||||
}
|
||||
if (create == NFSV4OPEN_CREATE)
|
||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, CREATE,
|
||||
LOCKPARENT | LOCKLEAF | SAVESTART);
|
||||
LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE);
|
||||
else
|
||||
NFSNAMEICNDSET(&named.ni_cnd, nd->nd_cred, LOOKUP,
|
||||
LOCKLEAF | SAVESTART);
|
||||
|
@ -195,7 +195,7 @@ tmpfs_lookup(struct vop_cachedlookup_args *v)
|
||||
/* Store the result of this lookup in the cache. Avoid this if the
|
||||
* request was for creation, as it does not improve timings on
|
||||
* emprical tests. */
|
||||
if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE)
|
||||
if ((cnp->cn_flags & MAKEENTRY) != 0)
|
||||
cache_enter(dvp, *vpp, cnp);
|
||||
|
||||
out:
|
||||
|
@ -536,6 +536,8 @@ unionfs_relookup(struct vnode *dvp, struct vnode **vpp,
|
||||
cn->cn_flags |= (cnp->cn_flags & (DOWHITEOUT | SAVESTART));
|
||||
else if (RENAME == nameiop)
|
||||
cn->cn_flags |= (cnp->cn_flags & SAVESTART);
|
||||
else if (nameiop == CREATE)
|
||||
cn->cn_flags |= NOCACHE;
|
||||
|
||||
vref(dvp);
|
||||
VOP_UNLOCK(dvp, LK_RELEASE);
|
||||
|
@ -160,8 +160,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
|
||||
LK_RETRY);
|
||||
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
} else if (error == ENOENT && (cnflags & MAKEENTRY) &&
|
||||
nameiop != CREATE)
|
||||
} else if (error == ENOENT && (cnflags & MAKEENTRY) != 0)
|
||||
cache_enter(dvp, NULLVP, cnp);
|
||||
|
||||
UNIONFS_INTERNAL_DEBUG("unionfs_lookup: leave (%d)\n", error);
|
||||
@ -337,7 +336,7 @@ unionfs_lookup(struct vop_cachedlookup_args *ap)
|
||||
if (lvp != NULLVP)
|
||||
vrele(lvp);
|
||||
|
||||
if (error == ENOENT && (cnflags & MAKEENTRY) && nameiop != CREATE)
|
||||
if (error == ENOENT && (cnflags & MAKEENTRY) != 0)
|
||||
cache_enter(dvp, NULLVP, cnp);
|
||||
|
||||
UNIONFS_INTERNAL_DEBUG("unionfs_lookup: leave (%d)\n", error);
|
||||
|
@ -505,7 +505,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,
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, NOFOLLOW | LOCKPARENT | SAVENAME | NOCACHE,
|
||||
UIO_SYSSPACE, buf, fd, cap_rights_init(&rights, CAP_BINDAT), td);
|
||||
/* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */
|
||||
error = namei(&nd);
|
||||
|
@ -1269,8 +1269,9 @@ kern_mknodat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
|
||||
return (error);
|
||||
restart:
|
||||
bwillwrite();
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1,
|
||||
pathseg, path, fd, cap_rights_init(&rights, CAP_MKNODAT), td);
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
|
||||
NOCACHE, pathseg, path, fd, cap_rights_init(&rights, CAP_MKNODAT),
|
||||
td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
vp = nd.ni_vp;
|
||||
@ -1384,8 +1385,9 @@ kern_mkfifoat(struct thread *td, int fd, char *path, enum uio_seg pathseg,
|
||||
AUDIT_ARG_MODE(mode);
|
||||
restart:
|
||||
bwillwrite();
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1,
|
||||
pathseg, path, fd, cap_rights_init(&rights, CAP_MKFIFOAT), td);
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
|
||||
NOCACHE, pathseg, path, fd, cap_rights_init(&rights, CAP_MKFIFOAT),
|
||||
td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
if (nd.ni_vp != NULL) {
|
||||
@ -1530,8 +1532,9 @@ kern_linkat(struct thread *td, int fd1, int fd2, char *path1, char *path2,
|
||||
vrele(vp);
|
||||
return (EPERM); /* POSIX */
|
||||
}
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE2,
|
||||
segflg, path2, fd2, cap_rights_init(&rights, CAP_LINKAT), td);
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE2 |
|
||||
NOCACHE, segflg, path2, fd2, cap_rights_init(&rights, CAP_LINKAT),
|
||||
td);
|
||||
if ((error = namei(&nd)) == 0) {
|
||||
if (nd.ni_vp != NULL) {
|
||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||
@ -1650,8 +1653,9 @@ kern_symlinkat(struct thread *td, char *path1, int fd, char *path2,
|
||||
AUDIT_ARG_TEXT(syspath);
|
||||
restart:
|
||||
bwillwrite();
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1,
|
||||
segflg, path2, fd, cap_rights_init(&rights, CAP_SYMLINKAT), td);
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
|
||||
NOCACHE, segflg, path2, fd, cap_rights_init(&rights, CAP_SYMLINKAT),
|
||||
td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
goto out;
|
||||
if (nd.ni_vp) {
|
||||
@ -3581,8 +3585,9 @@ kern_mkdirat(struct thread *td, int fd, char *path, enum uio_seg segflg,
|
||||
AUDIT_ARG_MODE(mode);
|
||||
restart:
|
||||
bwillwrite();
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1,
|
||||
segflg, path, fd, cap_rights_init(&rights, CAP_MKDIRAT), td);
|
||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 |
|
||||
NOCACHE, segflg, path, fd, cap_rights_init(&rights, CAP_MKDIRAT),
|
||||
td);
|
||||
nd.ni_cnd.cn_flags |= WILLBEDIR;
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
|
@ -189,7 +189,11 @@ vn_open_cred(struct nameidata *ndp, int *flagp, int cmode, u_int vn_open_flags,
|
||||
fmode = *flagp;
|
||||
if (fmode & O_CREAT) {
|
||||
ndp->ni_cnd.cn_nameiop = CREATE;
|
||||
ndp->ni_cnd.cn_flags = ISOPEN | LOCKPARENT | LOCKLEAF;
|
||||
/*
|
||||
* Set NOCACHE to avoid flushing the cache when
|
||||
* rolling in many files at once.
|
||||
*/
|
||||
ndp->ni_cnd.cn_flags = ISOPEN | LOCKPARENT | LOCKLEAF | NOCACHE;
|
||||
if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0)
|
||||
ndp->ni_cnd.cn_flags |= FOLLOW;
|
||||
if (!(vn_open_flags & VN_OPEN_NOAUDIT))
|
||||
|
@ -1184,8 +1184,7 @@ nfs_lookup(struct vop_lookup_args *ap)
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
|
||||
if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE &&
|
||||
dattrflag) {
|
||||
if ((cnp->cn_flags & MAKEENTRY) != 0 && dattrflag) {
|
||||
/*
|
||||
* Cache the modification time of the parent
|
||||
* directory from the post-op attributes in
|
||||
|
@ -1217,7 +1217,7 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
|
||||
nd.ni_cnd.cn_cred = cred;
|
||||
nd.ni_cnd.cn_nameiop = CREATE;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE;
|
||||
|
||||
/*
|
||||
* Call namei and do initial cleanup to get a few things
|
||||
@ -1501,7 +1501,7 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
|
||||
nd.ni_cnd.cn_cred = cred;
|
||||
nd.ni_cnd.cn_nameiop = CREATE;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | NOCACHE;
|
||||
|
||||
/*
|
||||
* Handle nfs_namei() call. If an error occurs, the nd structure
|
||||
@ -2030,7 +2030,7 @@ nfsrv_link(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
VOP_UNLOCK(vp, 0);
|
||||
nd.ni_cnd.cn_cred = cred;
|
||||
nd.ni_cnd.cn_nameiop = CREATE;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT | NOCACHE;
|
||||
error = nfs_namei(&nd, nfsd, dfhp, len, slp, nam, &md, &dpos,
|
||||
&dirp, v3, &dirfor, &dirfor_ret, FALSE);
|
||||
if (dirp && !v3) {
|
||||
@ -2153,7 +2153,7 @@ nfsrv_symlink(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
nfsm_srvnamesiz(len);
|
||||
nd.ni_cnd.cn_cred = cred;
|
||||
nd.ni_cnd.cn_nameiop = CREATE;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART | NOCACHE;
|
||||
error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
|
||||
&dirp, v3, &dirfor, &dirfor_ret, FALSE);
|
||||
if (error == 0) {
|
||||
@ -2325,7 +2325,7 @@ nfsrv_mkdir(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
|
||||
nfsm_srvnamesiz(len);
|
||||
nd.ni_cnd.cn_cred = cred;
|
||||
nd.ni_cnd.cn_nameiop = CREATE;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT;
|
||||
nd.ni_cnd.cn_flags = LOCKPARENT | NOCACHE;
|
||||
|
||||
error = nfs_namei(&nd, nfsd, fhp, len, slp, nam, &md, &dpos,
|
||||
&dirp, v3, &dirfor, &dirfor_ret, FALSE);
|
||||
|
@ -256,7 +256,8 @@ ffs_snapshot(mp, snapfile)
|
||||
* Create the snapshot file.
|
||||
*/
|
||||
restart:
|
||||
NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF, UIO_SYSSPACE, snapfile, td);
|
||||
NDINIT(&nd, CREATE, LOCKPARENT | LOCKLEAF | NOCACHE, UIO_SYSSPACE,
|
||||
snapfile, td);
|
||||
if ((error = namei(&nd)) != 0)
|
||||
return (error);
|
||||
if (nd.ni_vp != NULL) {
|
||||
|
@ -550,7 +550,7 @@ ufs_lookup_ino(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp,
|
||||
/*
|
||||
* Insert name into cache (as non-existent) if appropriate.
|
||||
*/
|
||||
if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE)
|
||||
if ((cnp->cn_flags & MAKEENTRY) != 0)
|
||||
cache_enter(vdp, NULL, cnp);
|
||||
return (ENOENT);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user