From c7520caa4f57b5022db419d69e44832f67926fe5 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Thu, 22 Oct 2020 19:28:12 +0000 Subject: vfs: prevent avoidable evictions on mkdir of existing directories mkdir -p /foo/bar/baz will mkdir each path component and ignore EEXIST. The NOCACHE lookup will make the namecache unnecessarily evict the existing entry, and then fallback to the fs lookup routine eventually leading namei to return an error as the directory is already there. For invocations like mkdir -p /usr/obj/usr/src/sys/GENERIC/modules this triggers fallbacks to the slowpath for concurrently executing lookups. Tested by: pho Discussed with: kib --- sys/sys/vnode.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'sys/sys/vnode.h') diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 5b330b508572..66ee5d0fb144 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -644,6 +644,15 @@ void cache_purge_negative(struct vnode *vp); void cache_rename(struct vnode *fdvp, struct vnode *fvp, struct vnode *tdvp, struct vnode *tvp, struct componentname *fcnp, struct componentname *tcnp); void cache_purgevfs(struct mount *mp); +#ifdef INVARIANTS +void cache_validate(struct vnode *dvp, struct vnode *vp, + struct componentname *cnp); +#else +static inline void +cache_validate(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) +{ +} +#endif int change_dir(struct vnode *vp, struct thread *td); void cvtstat(struct stat *st, struct ostat *ost); void freebsd11_cvtnstat(struct stat *sb, struct nstat *nsb); @@ -880,6 +889,7 @@ void vop_lock_debugpost(void *a, int rc); void vop_unlock_debugpre(void *a); void vop_need_inactive_debugpre(void *a); void vop_need_inactive_debugpost(void *a, int rc); +void vop_mkdir_debugpost(void *a, int rc); #else #define vop_fplookup_vexec_debugpre(x) do { } while (0) #define vop_fplookup_vexec_debugpost(x, y) do { } while (0) @@ -889,6 +899,7 @@ void vop_need_inactive_debugpost(void *a, int rc); #define vop_unlock_debugpre(x) do { } while (0) #define vop_need_inactive_debugpre(x) do { } while (0) #define vop_need_inactive_debugpost(x, y) do { } while (0) +#define vop_mkdir_debugpost(x, y) do { } while (0) #endif void vop_rename_fail(struct vop_rename_args *ap); -- cgit v1.2.3