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 *,