Index | Thread | Search

From:
Christian Schulte <cs@schulte.it>
Subject:
Remove memcpy from cache_lookup.c
To:
tech@openbsd.org
Date:
Mon, 6 Apr 2026 00:45:51 +0200

Download raw body.

Thread
  • Christian Schulte:

    Remove memcpy from cache_lookup.c

Currently cache_lookup copies the name to lookup to the stack
on every call just to perform the lookup. This diff makes memcpy
disappear from cache_lookup. By reordering the members of
struct namecache it is possible to add a new member nc_nptr
by still decreasing it's size on 64 bit machines by 8 bytes.
Increases the size by 4 byte on 32 bit machines, though.

Index: sys/sys/namei.h
===================================================================
RCS file: /cvs/src/sys/sys/namei.h,v
diff -u -p -u -r1.51 namei.h
--- sys/sys/namei.h	8 Mar 2026 16:41:19 -0000	1.51
+++ sys/sys/namei.h	2 Apr 2026 00:56:06 -0000
@@ -174,13 +174,14 @@ void ndinitat(struct nameidata *ndp, u_l
 #define	NAMECACHE_MAXLEN 31 /* maximum name segment length we bother with */
 
 struct	namecache {
+	struct	vnode *nc_dvp;		/* vnode of parent of name */
+	struct	vnode *nc_vp;		/* vnode the name refers to */
+	char	*nc_nptr;		/* pointer to segment name */
 	TAILQ_ENTRY(namecache) nc_lru;	/* Regular Entry LRU chain */
 	TAILQ_ENTRY(namecache) nc_neg;	/* Negative Entry LRU chain */
 	RBT_ENTRY(namecache) n_rbcache;	/* Namecache rb tree from vnode */
 	TAILQ_ENTRY(namecache) nc_me;	/* ncp's referring to me */
-	struct	vnode *nc_dvp;		/* vnode of parent of name */
 	u_long	nc_dvpid;		/* capability number of nc_dvp */
-	struct	vnode *nc_vp;		/* vnode the name refers to */
 	u_long	nc_vpid;		/* capability number of nc_vp */
 	char	nc_nlen;		/* length of name */
 	char	nc_name[NAMECACHE_MAXLEN];	/* segment name */
Index: sys/kern/vfs_cache.c
===================================================================
RCS file: /cvs/src/sys/kern/vfs_cache.c,v
diff -u -p -u -r1.58 vfs_cache.c
--- sys/kern/vfs_cache.c	14 Aug 2022 01:58:28 -0000	1.58
+++ sys/kern/vfs_cache.c	2 Apr 2026 00:56:17 -0000
@@ -75,7 +75,7 @@ static inline int
 namecache_compare(const struct namecache *n1, const struct namecache *n2)
 {
 	if (n1->nc_nlen == n2->nc_nlen)
-		return (memcmp(n1->nc_name, n2->nc_name, n1->nc_nlen));
+		return (memcmp(n1->nc_nptr, n2->nc_nptr, n1->nc_nlen));
 	else
 		return (n1->nc_nlen - n2->nc_nlen);
 }
@@ -158,7 +158,7 @@ cache_lookup(struct vnode *dvp, struct v
 
 	/* lookup in directory vnode's redblack tree */
 	n.nc_nlen = cnp->cn_namelen;
-	memcpy(n.nc_name, cnp->cn_nameptr, n.nc_nlen);
+	n.nc_nptr = cnp->cn_nameptr;
 	ncp = RBT_FIND(namecache_rb_cache, &dvp->v_nc_tree, &n);
 
 	if (ncp == NULL) {
@@ -369,6 +369,7 @@ cache_enter(struct vnode *dvp, struct vn
 	ncp->nc_dvp = dvp;
 	ncp->nc_dvpid = dvp->v_id;
 	ncp->nc_nlen = cnp->cn_namelen;
+	ncp->nc_nptr = ncp->nc_name;
 	memcpy(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen);
 	if (RBT_EMPTY(namecache_rb_cache, &dvp->v_nc_tree)) {
 		vhold(dvp);