Module Name:    src
Committed By:   hannken
Date:           Tue Mar 17 09:38:21 UTC 2015

Modified Files:
        src/sys/kern: vfs_vnode.c
        src/sys/sys: mount.h param.h vnode.h

Log Message:
Add new operation "vcache_new()" to allocate and initialise a new
vnode/fsnode pair:

int
vcache_new(struct mount *mp, struct vnode *dvp, struct vattr *vap,
    kauth_cred_t cred, struct vnode **vpp)

where dvp is the (referenced) directory where we want to create the
new node, vap passes va_type, va_mode and possibly va_rdev and cred
gives the credentials to setup uid/guid.

The node returned from vcache_new() is referenced, fully initialised
and has link count zero.

Welcome to NetBSD 7.99.7


To generate a diff of this commit:
cvs rdiff -u -r1.39 -r1.40 src/sys/kern/vfs_vnode.c
cvs rdiff -u -r1.215 -r1.216 src/sys/sys/mount.h
cvs rdiff -u -r1.466 -r1.467 src/sys/sys/param.h
cvs rdiff -u -r1.249 -r1.250 src/sys/sys/vnode.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_vnode.c
diff -u src/sys/kern/vfs_vnode.c:1.39 src/sys/kern/vfs_vnode.c:1.40
--- src/sys/kern/vfs_vnode.c:1.39	Fri Oct  3 14:45:38 2014
+++ src/sys/kern/vfs_vnode.c	Tue Mar 17 09:38:21 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_vnode.c,v 1.39 2014/10/03 14:45:38 hannken Exp $	*/
+/*	$NetBSD: vfs_vnode.c,v 1.40 2015/03/17 09:38:21 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
@@ -116,7 +116,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.39 2014/10/03 14:45:38 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_vnode.c,v 1.40 2015/03/17 09:38:21 hannken Exp $");
 
 #define _VFS_VNODE_PRIVATE
 
@@ -1330,6 +1330,82 @@ again:
 }
 
 /*
+ * Create a new vnode / fs node pair and return it referenced through vpp.
+ */
+int
+vcache_new(struct mount *mp, struct vnode *dvp, struct vattr *vap,
+    kauth_cred_t cred, struct vnode **vpp)
+{
+	int error;
+	uint32_t hash;
+	struct vnode *vp;
+	struct vcache_node *new_node;
+	struct vcache_node *old_node __diagused;
+
+	*vpp = NULL;
+
+	/* Allocate and initialize a new vcache / vnode pair. */
+	error = vfs_busy(mp, NULL);
+	if (error)
+		return error;
+	new_node = pool_cache_get(vcache.pool, PR_WAITOK);
+	new_node->vn_key.vk_mount = mp;
+	new_node->vn_vnode = NULL;
+	vp = vnalloc(NULL);
+
+	/* Create and load the fs node. */
+	vp->v_iflag |= VI_CHANGING;
+	error = VFS_NEWVNODE(mp, dvp, vp, vap, cred,
+	    &new_node->vn_key.vk_key_len, &new_node->vn_key.vk_key);
+	if (error) {
+		pool_cache_put(vcache.pool, new_node);
+		KASSERT(vp->v_usecount == 1);
+		vp->v_usecount = 0;
+		vnfree(vp);
+		vfs_unbusy(mp, false, NULL);
+		KASSERT(*vpp == NULL);
+		return error;
+	}
+	KASSERT(new_node->vn_key.vk_key != NULL);
+	KASSERT(vp->v_op != NULL);
+	hash = vcache_hash(&new_node->vn_key);
+
+	/* Wait for previous instance to be reclaimed, then insert new node. */
+	mutex_enter(&vcache.lock);
+	while ((old_node = vcache_hash_lookup(&new_node->vn_key, hash))) {
+#ifdef DIAGNOSTIC
+		if (old_node->vn_vnode != NULL)
+			mutex_enter(old_node->vn_vnode->v_interlock);
+		KASSERT(old_node->vn_vnode == NULL ||
+		    (old_node->vn_vnode->v_iflag & (VI_XLOCK | VI_CLEAN)) != 0);
+		if (old_node->vn_vnode != NULL)
+			mutex_exit(old_node->vn_vnode->v_interlock);
+#endif
+		mutex_exit(&vcache.lock);
+		kpause("vcache", false, mstohz(20), NULL);
+		mutex_enter(&vcache.lock);
+	}
+	SLIST_INSERT_HEAD(&vcache.hashtab[hash & vcache.hashmask],
+	    new_node, vn_hash);
+	mutex_exit(&vcache.lock);
+	vfs_insmntque(vp, mp);
+	if ((mp->mnt_iflag & IMNT_MPSAFE) != 0)
+		vp->v_vflag |= VV_MPSAFE;
+	vfs_unbusy(mp, true, NULL);
+
+	/* Finished loading, finalize node. */
+	mutex_enter(&vcache.lock);
+	new_node->vn_vnode = vp;
+	mutex_exit(&vcache.lock);
+	mutex_enter(vp->v_interlock);
+	vp->v_iflag &= ~VI_CHANGING;
+	cv_broadcast(&vp->v_cv);
+	mutex_exit(vp->v_interlock);
+	*vpp = vp;
+	return 0;
+}
+
+/*
  * Prepare key change: lock old and new cache node.
  * Return an error if the new node already exists.
  */

Index: src/sys/sys/mount.h
diff -u src/sys/sys/mount.h:1.215 src/sys/sys/mount.h:1.216
--- src/sys/sys/mount.h:1.215	Sat Jun 28 22:27:50 2014
+++ src/sys/sys/mount.h	Tue Mar 17 09:38:21 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: mount.h,v 1.215 2014/06/28 22:27:50 dholland Exp $	*/
+/*	$NetBSD: mount.h,v 1.216 2015/03/17 09:38:21 hannken Exp $	*/
 
 /*
  * Copyright (c) 1989, 1991, 1993
@@ -100,6 +100,7 @@
 #ifndef _STANDALONE
 
 struct vnode;
+struct vattr;
 
 /*
  * Structure per mounted file system.  Each mounted file system has an
@@ -222,6 +223,9 @@ struct vfsops {
 	int	(*vfs_vget)	(struct mount *, ino_t, struct vnode **);
 	int	(*vfs_loadvnode) (struct mount *, struct vnode *,
 				    const void *, size_t, const void **);
+	int	(*vfs_newvnode) (struct mount *, struct vnode *, struct vnode *,
+				    struct vattr *, kauth_cred_t,
+				    size_t *, const void **);
 	int	(*vfs_fhtovp)	(struct mount *, struct fid *,
 				    struct vnode **);
 	int	(*vfs_vptofh)	(struct vnode *, struct fid *, size_t *);
@@ -246,6 +250,8 @@ struct vfsops {
 #define VFS_VGET(MP, INO, VPP)    (*(MP)->mnt_op->vfs_vget)(MP, INO, VPP)
 #define VFS_LOADVNODE(MP, VP, KEY, KEY_LEN, NEW_KEY) \
 	(*(MP)->mnt_op->vfs_loadvnode)(MP, VP, KEY, KEY_LEN, NEW_KEY)
+#define VFS_NEWVNODE(MP, DVP, VP, VAP, CRED, NEW_LEN, NEW_KEY) \
+	(*(MP)->mnt_op->vfs_newvnode)(MP, DVP, VP, VAP, CRED, NEW_LEN, NEW_KEY)
 
 #define VFS_RENAMELOCK_ENTER(MP)  (*(MP)->mnt_op->vfs_renamelock_enter)(MP)
 #define VFS_RENAMELOCK_EXIT(MP)   (*(MP)->mnt_op->vfs_renamelock_exit)(MP)
@@ -287,6 +293,9 @@ int	fsname##_sync(struct mount *, int, s
 int	fsname##_vget(struct mount *, ino_t, struct vnode **);		\
 int	fsname##_loadvnode(struct mount *, struct vnode *,		\
 		const void *, size_t, const void **);			\
+int	fsname##_newvnode(struct mount *, struct vnode *,		\
+		struct vnode *, struct vattr *, kauth_cred_t,		\
+		size_t *, const void **);				\
 int	fsname##_fhtovp(struct mount *, struct fid *, struct vnode **);	\
 int	fsname##_vptofh(struct vnode *, struct fid *, size_t *);	\
 void	fsname##_init(void);						\

Index: src/sys/sys/param.h
diff -u src/sys/sys/param.h:1.466 src/sys/sys/param.h:1.467
--- src/sys/sys/param.h:1.466	Sat Mar  7 16:34:55 2015
+++ src/sys/sys/param.h	Tue Mar 17 09:38:21 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: param.h,v 1.466 2015/03/07 16:34:55 christos Exp $	*/
+/*	$NetBSD: param.h,v 1.467 2015/03/17 09:38:21 hannken Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -63,7 +63,7 @@
  *	2.99.9		(299000900)
  */
 
-#define	__NetBSD_Version__	799000600	/* NetBSD 7.99.6 */
+#define	__NetBSD_Version__	799000700	/* NetBSD 7.99.7 */
 
 #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
     (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)

Index: src/sys/sys/vnode.h
diff -u src/sys/sys/vnode.h:1.249 src/sys/sys/vnode.h:1.250
--- src/sys/sys/vnode.h:1.249	Sat Jul  5 09:33:15 2014
+++ src/sys/sys/vnode.h	Tue Mar 17 09:38:21 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: vnode.h,v 1.249 2014/07/05 09:33:15 hannken Exp $	*/
+/*	$NetBSD: vnode.h,v 1.250 2015/03/17 09:38:21 hannken Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -557,6 +557,8 @@ struct vnode *
 void	vnfree(struct vnode *);
 void	vremfree(struct vnode *);
 int	vcache_get(struct mount *, const void *, size_t, struct vnode **);
+int	vcache_new(struct mount *, struct vnode *,
+	    struct vattr *, kauth_cred_t, struct vnode **);
 int	vcache_rekey_enter(struct mount *, struct vnode *,
 	    const void *, size_t, const void *, size_t);
 void	vcache_rekey_exit(struct mount *, struct vnode *,

Reply via email to