svn commit: r312432 - head/sys/fs/tmpfs

Konstantin Belousov kib at FreeBSD.org
Thu Jan 19 19:46:50 UTC 2017


Author: kib
Date: Thu Jan 19 19:46:49 2017
New Revision: 312432
URL: https://svnweb.freebsd.org/changeset/base/312432

Log:
  Add mount option for tmpfs(5) to not use namecache.
  
  The option "nonc" disables using of namecache for the created mount,
  by default namecache is used.  The rationale for the option is that
  namecache duplicates the information which is already kept in memory
  by tmpfs.  Since it believed that namecache scales better than tmpfs,
  or will scale better, do not enable the option by default.  On the
  other hand, smaller machines may benefit from lesser namecache
  pressure.
  
  Discussed with:	mjg
  Tested by:	pho (as part of larger patch)
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

Modified:
  head/sys/fs/tmpfs/tmpfs.h
  head/sys/fs/tmpfs/tmpfs_subr.c
  head/sys/fs/tmpfs/tmpfs_vfsops.c
  head/sys/fs/tmpfs/tmpfs_vnops.c
  head/sys/fs/tmpfs/tmpfs_vnops.h

Modified: head/sys/fs/tmpfs/tmpfs.h
==============================================================================
--- head/sys/fs/tmpfs/tmpfs.h	Thu Jan 19 19:46:15 2017	(r312431)
+++ head/sys/fs/tmpfs/tmpfs.h	Thu Jan 19 19:46:49 2017	(r312432)
@@ -385,7 +385,9 @@ struct tmpfs_mount {
 	uma_zone_t		tm_node_pool;
 
 	/* Read-only status. */
-	int			tm_ronly;
+	bool			tm_ronly;
+	/* Do not use namecache. */
+	bool			tm_nonc;
 };
 #define	TMPFS_LOCK(tm) mtx_lock(&(tm)->tm_allnode_lock)
 #define	TMPFS_UNLOCK(tm) mtx_unlock(&(tm)->tm_allnode_lock)
@@ -530,4 +532,11 @@ VP_TO_TMPFS_DIR(struct vnode *vp)
 	return (node);
 }
 
+static inline bool
+tmpfs_use_nc(struct vnode *vp)
+{
+
+	return (!(VFS_TO_TMPFS(vp->v_mount)->tm_nonc));
+}
+
 #endif /* _FS_TMPFS_TMPFS_H_ */

Modified: head/sys/fs/tmpfs/tmpfs_subr.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_subr.c	Thu Jan 19 19:46:15 2017	(r312431)
+++ head/sys/fs/tmpfs/tmpfs_subr.c	Thu Jan 19 19:46:49 2017	(r312432)
@@ -591,7 +591,8 @@ loop:
 	TMPFS_NODE_UNLOCK(node);
 
 	/* Get a new vnode and associate it with our node. */
-	error = getnewvnode("tmpfs", mp, &tmpfs_vnodeop_entries, &vp);
+	error = getnewvnode("tmpfs", mp, VFS_TO_TMPFS(mp)->tm_nonc ?
+	    &tmpfs_vnodeop_nonc_entries : &tmpfs_vnodeop_entries, &vp);
 	if (error != 0)
 		goto unlock;
 	MPASS(vp != NULL);

Modified: head/sys/fs/tmpfs/tmpfs_vfsops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vfsops.c	Thu Jan 19 19:46:15 2017	(r312431)
+++ head/sys/fs/tmpfs/tmpfs_vfsops.c	Thu Jan 19 19:46:49 2017	(r312432)
@@ -79,7 +79,7 @@ static void	tmpfs_susp_clean(struct moun
 
 static const char *tmpfs_opts[] = {
 	"from", "size", "maxfilesize", "inodes", "uid", "gid", "mode", "export",
-	"union", NULL
+	"union", "nonc", NULL
 };
 
 static const char *tmpfs_updateopts[] = {
@@ -138,6 +138,7 @@ tmpfs_mount(struct mount *mp)
 	struct tmpfs_node *root;
 	struct thread *td = curthread;
 	int error;
+	bool nonc;
 	/* Size counters. */
 	u_quad_t pages;
 	off_t nodes_max, size_max, maxfilesize;
@@ -186,6 +187,7 @@ tmpfs_mount(struct mount *mp)
 		size_max = 0;
 	if (vfs_getopt_size(mp->mnt_optnew, "maxfilesize", &maxfilesize) != 0)
 		maxfilesize = 0;
+	nonc = vfs_getopt(mp->mnt_optnew, "nonc", NULL, NULL) == 0;
 
 	/* Do not allow mounts if we do not have enough memory to preserve
 	 * the minimum reserved pages. */
@@ -236,6 +238,7 @@ tmpfs_mount(struct mount *mp)
 	    sizeof(struct tmpfs_node), tmpfs_node_ctor, tmpfs_node_dtor,
 	    tmpfs_node_init, tmpfs_node_fini, UMA_ALIGN_PTR, 0);
 	tmp->tm_ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
+	tmp->tm_nonc = nonc;
 
 	/* Allocate the root node. */
 	error = tmpfs_alloc_node(mp, tmp, VDIR, root_uid, root_gid,

Modified: head/sys/fs/tmpfs/tmpfs_vnops.c
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vnops.c	Thu Jan 19 19:46:15 2017	(r312431)
+++ head/sys/fs/tmpfs/tmpfs_vnops.c	Thu Jan 19 19:46:49 2017	(r312432)
@@ -76,11 +76,8 @@ tmpfs_vn_get_ino_alloc(struct mount *mp,
 }
 
 static int
-tmpfs_lookup(struct vop_cachedlookup_args *v)
+tmpfs_lookup1(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp)
 {
-	struct vnode *dvp = v->a_dvp;
-	struct vnode **vpp = v->a_vpp;
-	struct componentname *cnp = v->a_cnp;
 	struct tmpfs_dirent *de;
 	struct tmpfs_node *dnode, *pnode;
 	struct tmpfs_mount *tm;
@@ -213,7 +210,7 @@ tmpfs_lookup(struct vop_cachedlookup_arg
 	 * request was for creation, as it does not improve timings on
 	 * emprical tests.
 	 */
-	if ((cnp->cn_flags & MAKEENTRY) != 0)
+	if ((cnp->cn_flags & MAKEENTRY) != 0 && tmpfs_use_nc(dvp))
 		cache_enter(dvp, *vpp, cnp);
 
 out:
@@ -227,6 +224,20 @@ out:
 }
 
 static int
+tmpfs_cached_lookup(struct vop_cachedlookup_args *v)
+{
+
+	return (tmpfs_lookup1(v->a_dvp, v->a_vpp, v->a_cnp));
+}
+
+static int
+tmpfs_lookup(struct vop_lookup_args *v)
+{
+
+	return (tmpfs_lookup1(v->a_dvp, v->a_vpp, v->a_cnp));
+}
+
+static int
 tmpfs_create(struct vop_create_args *v)
 {
 	struct vnode *dvp = v->a_dvp;
@@ -238,7 +249,7 @@ tmpfs_create(struct vop_create_args *v)
 	MPASS(vap->va_type == VREG || vap->va_type == VSOCK);
 
 	error = tmpfs_alloc_file(dvp, vpp, vap, cnp, NULL);
-	if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0)
+	if (error == 0 && (cnp->cn_flags & MAKEENTRY) != 0 && tmpfs_use_nc(dvp))
 		cache_enter(dvp, *vpp, cnp);
 	return (error);
 }
@@ -1013,10 +1024,12 @@ tmpfs_rename(struct vop_rename_args *v)
 
 	tmpfs_dir_attach(tdvp, de);
 
-	cache_purge(fvp);
-	if (tvp != NULL)
-		cache_purge(tvp);
-	cache_purge_negative(tdvp);
+	if (tmpfs_use_nc(fvp)) {
+		cache_purge(fvp);
+		if (tvp != NULL)
+			cache_purge(tvp);
+		cache_purge_negative(tdvp);
+	}
 
 	error = 0;
 
@@ -1129,8 +1142,10 @@ tmpfs_rmdir(struct vop_rmdir_args *v)
 	    TMPFS_NODE_MODIFIED;
 	TMPFS_NODE_UNLOCK(dnode);
 
-	cache_purge(dvp);
-	cache_purge(vp);
+	if (tmpfs_use_nc(dvp)) {
+		cache_purge(dvp);
+		cache_purge(vp);
+	}
 
 	/* Free the directory entry we just deleted.  Note that the node
 	 * referred by it will not be removed until the vnode is really
@@ -1274,7 +1289,8 @@ tmpfs_reclaim(struct vop_reclaim_args *v
 	else
 		vnode_destroy_vobject(vp);
 	vp->v_object = NULL;
-	cache_purge(vp);
+	if (tmpfs_use_nc(vp))
+		cache_purge(vp);
 
 	TMPFS_NODE_LOCK(node);
 	tmpfs_free_vp(vp);
@@ -1538,7 +1554,7 @@ restart:
 struct vop_vector tmpfs_vnodeop_entries = {
 	.vop_default =			&default_vnodeops,
 	.vop_lookup =			vfs_cache_lookup,
-	.vop_cachedlookup =		tmpfs_lookup,
+	.vop_cachedlookup =		tmpfs_cached_lookup,
 	.vop_create =			tmpfs_create,
 	.vop_mknod =			tmpfs_mknod,
 	.vop_open =			tmpfs_open,
@@ -1567,3 +1583,10 @@ struct vop_vector tmpfs_vnodeop_entries 
 	.vop_vptocnp =			tmpfs_vptocnp,
 };
 
+/*
+ * Same vector for mounts which do not use namecache.
+ */
+struct vop_vector tmpfs_vnodeop_nonc_entries = {
+	.vop_default =			&tmpfs_vnodeop_entries,
+	.vop_lookup =			tmpfs_lookup,
+};

Modified: head/sys/fs/tmpfs/tmpfs_vnops.h
==============================================================================
--- head/sys/fs/tmpfs/tmpfs_vnops.h	Thu Jan 19 19:46:15 2017	(r312431)
+++ head/sys/fs/tmpfs/tmpfs_vnops.h	Thu Jan 19 19:46:49 2017	(r312432)
@@ -44,6 +44,7 @@
  */
 
 extern struct vop_vector tmpfs_vnodeop_entries;
+extern struct vop_vector tmpfs_vnodeop_nonc_entries;
 
 vop_access_t	tmpfs_access;
 vop_getattr_t	tmpfs_getattr;


More information about the svn-src-all mailing list