Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Add new operation "vcache_new()" to allocate and initial...



details:   https://anonhg.NetBSD.org/src/rev/1c2d5526e8a0
branches:  trunk
changeset: 336755:1c2d5526e8a0
user:      hannken <hannken%NetBSD.org@localhost>
date:      Tue Mar 17 09:38:21 2015 +0000

description:
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

diffstat:

 sys/kern/vfs_vnode.c |  80 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 sys/sys/mount.h      |  11 ++++++-
 sys/sys/param.h      |   4 +-
 sys/sys/vnode.h      |   4 +-
 4 files changed, 93 insertions(+), 6 deletions(-)

diffs (183 lines):

diff -r 08257988d8a2 -r 1c2d5526e8a0 sys/kern/vfs_vnode.c
--- a/sys/kern/vfs_vnode.c      Tue Mar 17 09:27:09 2015 +0000
+++ b/sys/kern/vfs_vnode.c      Tue Mar 17 09:38:21 2015 +0000
@@ -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 @@
 }
 
 /*
+ * 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.
  */
diff -r 08257988d8a2 -r 1c2d5526e8a0 sys/sys/mount.h
--- a/sys/sys/mount.h   Tue Mar 17 09:27:09 2015 +0000
+++ b/sys/sys/mount.h   Tue Mar 17 09:38:21 2015 +0000
@@ -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 @@
        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 @@
 #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##_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);                                            \
diff -r 08257988d8a2 -r 1c2d5526e8a0 sys/sys/param.h
--- a/sys/sys/param.h   Tue Mar 17 09:27:09 2015 +0000
+++ b/sys/sys/param.h   Tue Mar 17 09:38:21 2015 +0000
@@ -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__)
diff -r 08257988d8a2 -r 1c2d5526e8a0 sys/sys/vnode.h
--- a/sys/sys/vnode.h   Tue Mar 17 09:27:09 2015 +0000
+++ b/sys/sys/vnode.h   Tue Mar 17 09:38:21 2015 +0000
@@ -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 @@
 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 *,



Home | Main Index | Thread Index | Old Index